• 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

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

  • 相关阅读:
    jquery drag
    regex moudle for python pretty hot
    雅虎站长工具
    online code review modrian & rietveld created by python creater
    sqlalchemy & elixir migrate tutorial
    http://djangopeople.net/ is pretty cool
    jquery easy drag
    网站更新部署站长手记20100924
    wsgi server & python deployment solution
    gevent 0.13.1 is out
  • 原文地址:https://www.cnblogs.com/ShuraK/p/7852461.html
Copyright © 2020-2023  润新知