题目: 牛客网链接
概述: 给出m条道路,n个村庄,看这些道路能不能让所有村庄联通起来,如果能,输出联通的最小代价,如果不能,输出问号。
思路: 最小生成树 Kruskal算法(并查集)。
如果每个是相联通的,那么他们应该有一个共同的最终根节点。我们可以找出来一个与其他比较。用来判断是否这是个连通图
#include <iostream>
#include <algorithm>
using namespace std;
//并查集用来存储父节点的数组
int father[200];
struct Edge{
int a, b, cost;
};
int find_father(int x)
{
while( x != father[x])
{
x = father[x];
}
return x;
}
//按照花费进行排序
bool cmp(Edge a, Edge b)
{
return a.cost < b.cost;
}
Edge edge[200];
int main()
{
int m, n;
while(scanf("%d%d", &n, &m) != EOF && n != 0)
{
int ans = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].cost);
}
//按照花费进行排序
sort(edge + 1, edge + 1 + n, cmp);
for(int i = 1; i <= m; i++) father[i] = i;
for(int i = 1; i <= n; i++)
{
int a = find_father(edge[i].a);
int b = find_father(edge[i].b);
if(a != b)
{
father[a] = b;
ans += edge[i].cost;
}
}
//如果每个是相联通的,那么他们应该有一个共同的最终根节点。我们可以找出来一个与其他比较。用来判断是否这是个连通图
bool flag = true;
int t = find_father(1);
for(int i = 2; i <= m; i++)
{
if(t != find_father(i))
{
flag = false;
break;
}
}
if(flag) cout << ans << endl;
else cout << "?" << endl;
}
return 0;
}