Sweet Butter 香甜的黄油

Sweet Butter 香甜的黄油

    题目大意:m个点,n头奶牛,p条边,每一头奶牛在一个点上,一个点可以有多只奶牛,求这样一个点,使得所有奶牛到这个点的距离之和最小。

    注释:n<=500 , m<=800 , p<=1450 , 连边的牧场之间的距离d<=255

      想法:显然,这是一个最短路问题,有两种途径:1. 跑多源最短路。2. 跑m遍单源最短路。

        第1种想法想到floyd , 时间复杂度O(m^3)=O(5.12*10^8),过不去,用第二种想法吧。

        由于floyd都T了,n遍Dijkstra的时间复杂度也是O(m^3),而另一种单源最短路是spfa,时间复杂度O(m*p+m*n)。所以,spfa才是我们想要的算法。

        首先,对于每一个节点跑一遍spfa,注意清数组。存边用邻接矩阵或链式前向星均可,博主在此采用链式前向星。

    最后,附上丑陋的代码...

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 queue<int>q;
 7 int f[10010],a[10010];
 8 bool v[10010];
 9 int to[10010],val[10010],next[10010],head[10010],tot;
10 void add(int x,int y,int z)//存边
11 {
12     to[++tot]=y;
13     val[tot]=z;
14     next[tot]=head[x];
15     head[x]=tot;
16 }
17 void spfa(int xp)//spfa,xp表示当前枚举的源点
18 {
19     memset(f,0x3f,sizeof(f));
20     memset(v,0,sizeof(v));
21     q.push(xp),f[xp]=0,v[xp]=1;
22     while(q.size())
23     {
24         int x,y;
25         x=q.front(),q.pop(),v[x]=0;
26         for(int i=head[x];i;i=next[i])
27         {
28             if(f[y=to[i]]>f[x]+val[i])
29             {
30                 f[y]=f[x]+val[i];
31                 if(v[y]==0) q.push(y),v[y]=1;
32             }
33         }
34     }
35 }
36 int main()
37 {
38     int n,m,p;
39     scanf("%d%d%d",&n,&m,&p);
40     for(int i=1;i<=n;i++)
41     {
42         scanf("%d",&a[i]);
43     }
44     int fr,t,va;
45     for(int i=1;i<=p;i++)
46     {
47         scanf("%d%d%d",&fr,&t,&va);
48         add(fr,t,va);//存双向边
49         add(t,fr,va);//存双向边
50     }
51     long long minn=9220000000000000ll;
52     for(int i=1;i<=m;i++)
53     {
54         spfa(i);
55         long long ans=0;
56         for(int j=1;j<=n;j++)
57         {
58             ans+=f[a[j]];
59         }
60         minn=min(ans,minn);
61     }
62     printf("%lld",minn);
63     return 0;
64 }

      小结,错误

            1.双向边,双向边,双向边

            2.line 60:写成了 ans=min ( minn , ans ) 全盘爆蛋

            3.因为本题不一定连通,所以在一定程度上我们需要考虑不连通的情况,所以ans和minn开long long 来解决。

  转载请注明:http://www.cnblogs.com/ShuraK/p/7852461.html

| 欢迎来原网站坐坐! >原文链接<

原文地址:https://www.cnblogs.com/ShuraK/p/7852461.html