最小生成树;
提前已经修好的路提前加入并查集;
个人比较喜欢并查集求解最小生成树
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int pre[110], map[110][110];
struct Kruskal
{
int a, b, cost;
};
Kruskal village[110 * 110 / 2];
bool cmp(const Kruskal &a, const Kruskal &b)
{
return a.cost < b.cost;
}
int unionsearch(int x) //查找根结点
{
return x == pre[x] ? x : unionsearch(pre[x]);
}
bool join(int x, int y)
{
int root1, root2;
root1 = unionsearch(x);
root2 = unionsearch(y);
if(root1 == root2)
return false;
pre[root1] = root2;
return true;
}
int main()
{
int num, k, already, a, b, x, y, sum;
while(scanf("%d", &num) != EOF)
{
memset(pre, 0, sizeof(pre));
memset(map, 0, sizeof(map));
for(int i = 1; i <= num; ++i)
pre[i] = i;
for(int i = 1; i <= num; ++i)
for(int j = 1; j <= num; ++j)
scanf("%d", &map[i][j]);
k = 0;
for(int i = 1; i <= num; ++i)
for(int j = i + 1; j <= num; ++j)
{
village[k].a = i;
village[k].b = j;
village[k].cost = map[i][j];
k++;
}
sort(village, village + k, cmp);
scanf("%d", &already);
for(int i = 1; i <= already; ++i)
{
scanf("%d%d", &a, &b);
x = unionsearch(a);
y = unionsearch(b);
if(x != y)
pre[x] = y;
}
sum = 0;
for(int i = 0; i < k; ++i)
if(join(village[i].a, village[i].b))
sum += village[i].cost;
printf("%d\n", sum);
}
return 0;
}