畅通工程

Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
 
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
 
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
 
Sample Input
3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
 
Sample Output
3 ?
并查集:判断最小生成树,先对边由小到大进行排序。合并操作后看是否是一个联通分量,如不是则不能畅通。
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int n,m;
int p[200];
int flag[200];
struct lmx{
 int x;
 int y;
 int val;
};
lmx lm[200];
bool cmp(lmx s,lmx t)
{
 return s.val<t.val;
}
void init(int m)
{
 int i;
 for(i=1;i<=m;i++)
 {
  p[i]=i;
 }
}
int finder(int x)
{
 if(x==p[x]) return x;
 else p[x]=finder(p[x]);
}
int  unioner(int x,int y)
{
 int t1=finder(x);
 int t2=finder(y);
 if(t1==t2) return 1;
 else {p[t1]=t2;return 0;}
}
int main()
{
     int i,sum,cnt;
  while(cin>>n>>m)
  {
   memset(flag,0,sizeof(flag));
   sum=0;
   cnt=0;
   if(n==0) break;
   init(m);
   for(i=1;i<=n;i++)
   {
    cin>>lm[i].x>>lm[i].y>>lm[i].val;
   }
   sort(lm+1,lm+n+1,cmp);
   for(i=1;i<=n;i++)
   {
    if(unioner(lm[i].x,lm[i].y)==0) sum+=lm[i].val;
   }
   for(i=1;i<=m;i++)
   {
             flag[finder(i)]=1;
   }
   for(i=1;i<=m;i++)
   {
    if(flag[i]) cnt++;
   }
   if(cnt==1) cout<<sum<<endl;
   else cout<<"?"<<endl;
  }
 return 0;
}
posted @ 2013-04-01 16:42  forevermemory  阅读(86)  评论(0编辑  收藏  举报