【并查集】畅通工程...

描述

省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。

输入

测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。

输出

对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。

样例输入

3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100

样例输出

3
?

题目来源

浙大计算机研究生复试上机考试-2007年

分析:
经典并查集类型题目。
反思:
RE了一次,数组开小了。
代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int p1;
int p2;
int cost;
}r[10010];
int f[10010],n,m;
bool cmp(node x,node y)
{
return x.cost<y.cost;
}
int findit(int x)
{
int root=x;
while(f[root]!=root)
{
root=f[root];
}
int ys=x,c;//借鉴,路径压缩.
while(ys!=root)
{
c=f[ys];
f[ys]=root;
ys=c;
}
return root;
}
bool Union(int x,int y)
{
int fx=findit(x);
int fy=findit(y);
if (fx!=fy)
{
f[fx]=fy;
return 1;
}
return 0;
}
int main()
{
while(cin>>n>>m&&n)
{
int ans=0;
memset(f,0,sizeof(f));
memset(r,0,sizeof®);
for (int i=1;i<=m;i++)
f[i]=i;
for (int i=0;i<n;i++)
{
scanf("%d%d%d",&r[i].p1,&r[i].p2,&r[i].cost);
}
sort(r,r+n,cmp);
for (int i=0;i<n;i++)
{
if(Union(r[i].p1,r[i].p2))
ans+=r[i].cost;
}
int t=0;
for (int i=1;i<=m;i++)
{
if (f[i]==i) t++;
}
if (t>1) cout<<"?"<<endl;
else cout<<ans<<endl;
}
return 0;
}

发布了122 篇原创文章 · 获赞 0 · 访问量 4671

猜你喜欢

转载自blog.csdn.net/Skynamer/article/details/104141407