并查集、最小生成树用Prime算法,注意细节即可
#include<iostream>
#include<cstring>
#include<algorithm>
#pragma warning(disable: 4996)
using namespace std;
const int NN = 100, INF = 99999999;
int a[NN][NN], f[NN];
int find(int x)
{//寻找根节点,即x点所在集合的标记值
if (x == f[x]) return x;
f[x] = find(f[x]);
return f[x];
}
int mer(int x, int y)
{
x = find(x);
y = find(y);
if (x != y)
f[x] = y;
return 1;
}
int main()
{
int n, m, x, y, z, sum;
while (cin >> m >> n && m)
{
sum = 0;
for (int i = 1; i <= n; i++)
f[i] = i;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++)
a[i][j] = INF;
while (m--)
{
scanf("%d %d %d", &x, &y, &z);
if (z == 0) continue;
x >= y ? a[x][y] = z : a[y][x] = z;
}
while (1)
{
int min0 = INF, flag = 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++)
if (find(i) != find(j) && a[i][j] < min0)
{
min0 = a[i][j];
x = i;
y = j;
flag = 0;
}
if (flag) break;
mer(x, y);
sum += a[x][y];
}//while
int p = 1;
for(int i = 2; i <= n; i++)//判断是否所有的村庄都属于同一个集合,不是的话说明不满足全部连通的条件,输出?
if (find(i - 1) != find(i))
{
p = 0;
break;
}
if (p)
cout << sum << endl;
else
cout << "?" << endl;
}
return 0;
}