题意:给定一个无向图,求他的最小生成树与最大生成树的平均值。
思路:用Kruskal正着求最小生成树,再倒着求最大生成树。
#include <bits/stdc++.h>
using namespace std;
struct node{
int x, y, w;
}edge[30000];
int cnt;
int n;
int fa[15000];
int cmp1(node a, node b)
{
return a.w < b.w;
}
int cmp2(node a, node b)
{
return a.w > b.w;
}
int find(int x)
{
if (fa[x]!=x)
fa[x] = find(fa[x]);
return fa[x];
}
int Kruskal()
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
fa[i] = i;
}
for (int i = 0; i < cnt; i++)
{
int a = find(edge[i].x);
int b = find(edge[i].y);
if (a!=b)
{
fa[a] = b;
sum+=edge[i].w;
}
}
return sum;
}
int main(void)
{
int T, cas=1;
scanf("%d", &T);
while (T--)
{
cnt = 0;
scanf("%d", &n);
int u, v, w;
while (scanf("%d %d %d", &u, &v, &w))
{
if (u+v+w==0)
break;
edge[cnt].x = u;
edge[cnt].y = v;
edge[cnt++].w = w;
edge[cnt].x = v;
edge[cnt].y = u;
edge[cnt++].w = w;
}
int ans = 0;
sort(edge, edge+cnt, cmp1);
ans += Kruskal();
sort(edge, edge+cnt, cmp2);
ans += Kruskal();
if (ans&1)
printf("Case %d: %d/2\n", cas++, ans);
else
printf("Case %d: %d\n", cas++, ans/2);
}
return 0;
}