市政府“惠民工程”的目标是在全市 n 个居民点间之架设煤气管道(但不一定有直接的管道相连,只要能间接通过管道可达即可)。很显然最多可架设 n(n−1)/2 条管道,然而实际上要连通 n 个居民点只需架设 n−1 条管道就可以了。现请你编写程序,计算出该惠民工程需要的最低成本。
输入格式
输入包含多组测试数据。每组数据第一行包含两个整数 n 和 m,表示居民点数量和评估管道数量。接下来 m 行,每行包含三个整数 a,b,c,表示居民点 a 和 b 之间架设管道需要 c的成本。居民点编号 1∼n。
输出格式
每组数据输出一行一个结果,表示全市管道畅通所需要的最低成本。若统计数据不足以保证畅通,则输出 ?。
数据范围
2≤n≤100,
1≤m≤n(n−1)2,
1≤a,b≤n,
1≤c≤100,
每个输入最多包含 100 组数据。
输入样例:
3 3
1 2 1
1 3 2
2 3 4
3 1
2 3 2
输出样例:
3
?
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110,M=N*(N-1)/2;
int n,m,fa[N];
struct edge{int a,b,c;
}e[M];
bool cmp(edge x,edge y)
{return x.c<y.c;
}
int find(int x)
{if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];
}
int main()
{while(cin>>n>>m){for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;e[i].a=a,e[i].b=b,e[i].c=c;}for(int i=1;i<=n;i++) fa[i]=i;sort(e,e+m,cmp);int cnt=n,res=0;for(int i=0;i<m;i++){int x=e[i].a,y=e[i].b,z=e[i].c;if(find(x)==find(y)) continue;fa[find(x)]=find(y);cnt--,res+=z;}if(cnt==1) cout<<res<<endl;else cout<<"?"<<endl;}return 0;
}