畅通工程
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从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;
}
#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;
}
为了明天所以选择坚定的执着今天。