还是畅通工程

Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
 
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
 
思路:完全的最小生成树,唯一区别是生成树一些边已经固定,需要事先将边加进数组flag中,当所有点都连通时,结束。
代码:

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
struct vertex{
int x,y;
int index;
}num[5008];
int flag[102];
int cmp(const void *a,const void *b)
{
  struct vertex *c,*d;
  c=(struct vertex *)a;
  d=(struct vertex *)b;
  return c->index-d->index;
}
int parent(int x)
{
  if(x==flag[x])
    return x;
  flag[x]=parent(flag[x]);
    return flag[x];
}
int main()
{
  int n,i,sum,ra,rb;
  while(scanf("%d",&n),n)
  {
    for(i=0;i<=n;i++)
    flag[i]=i;
    for(i=0;i<n*(n-1)/2;i++){
      int mark = 0;
      scanf("%d%d%d%d",&num[i].x,&num[i].y,&num[i].index,&mark);
      if(mark == 1){
        ra=parent(num[i].x);
        rb=parent(num[i].y);
        if(ra<rb)
          flag[rb]=ra;
        else flag[ra]=rb;
      }
    }
    qsort(num,n*(n-1)/2,sizeof(num[0]),cmp);
    sum=0;
    for(i=0;i<n*(n-1)/2;i++)
    {
      ra=parent(num[i].x);
      rb=parent(num[i].y);
      if(ra==rb)continue;
      else {
        sum+=num[i].index;
        if(ra<rb)
          flag[rb]=ra;
        else flag[ra]=rb;
      }
    }
    printf("%d\n",sum);
  }
  return 0;
}

posted @ 2016-07-06 22:13  SDAU_ZG  阅读(105)  评论(0)    收藏  举报