Problem E

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangran1111/article/details/51830403
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。<br>
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。<br><br>当N为0时输入结束。
 

Output
每个测试用例的输出占一行,输出全省畅通需要的最低成本。
 

Sample Input
 
  
3 1 2 1 0 1 3 2 0 2 3 4 0 3 1 2 1 0 1 3 2 0 2 3 4 1 3 1 2 1 0 1 3 2 1 2 3 4 1 0
 

Sample Output
 
  
3 1

0

代码:

#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std;  int pre[105]; struct node {  int p1;  int p2;              int v;                   } way[5000]; int m,n; void init() {     memset(pre,0,sizeof(pre));     memset(way,0,sizeof(way));     for(int i=1;i<=n;i++)      pre[i]=i; } int cmp(node a,node b)  {   return a.v<b.v; } int find(int x)                    {  int ret=x;  while(pre[ret]!=ret)    ret=pre[ret];   int t=x,r;   while(t!=ret)            {    r=pre[t];       pre[t]=ret;    t=r;   }   return ret; } int join(int x,int y)           {   int fx=find(x);   int fy=find(y);   if(fx!=fy)//这里做了一个优化,每次保证较大的点当做父节点,把较小的并入到大的中   {    if(fx<fy)      pre[fy]=fx;     else      pre[fx]=fy;      return 1;   }    return 0; } void Kruskal() {   int ans=0;   for(int i=0;i<m;i++)    if(join(way[i].p1,way[i].p2))     ans+=way[i].v;    printf("%d\n",ans); } int main() {     while(scanf("%d",&n),n)   {    m=n*(n-1)/2;    init();    for(int i=0;i<m;i++)    {        int a,b,v,flag;        scanf("%d%d%d%d",&a,&b,&v,&flag);        way[i].p1=a;        way[i].p2=b;        if(flag)          way[i].v=0;         else          way[i].v=v;    }      sort(way,way+m,cmp);      Kruskal();   }   return 0; } 

猜你喜欢

转载自blog.csdn.net/wangran1111/article/details/51830403