题目大意:判断最小生成树是否唯一
题目分析:求次小生成树,判断与最小生成树权值是否相等。
如何求次小生成树:先将出现权值相同的边标记,跑一次Kruscal,求出mst,并记录选出来的边,在选出来的边中任选一条被相同权值标记过的边,删掉,再求mst,记录最小值。
trick:删边Kruscal的时候,注意判断图不连通,因为如果删掉的是一条关键边,导致图不连通,求出的新生成树会少一条边,但是权值可能会和最小生成树相同。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 104;
const int M = 100004;
struct node
{
int u,v,val;
bool sameval;
}edge[M];
int set[N];
bool flag[M];
int stack[N];
int ans;
int m,n;
int cmp(struct node a,struct node b)
{
return a.val < b.val;
}
int find(int x)
{
if(set[x] != x)
set[x] = find(set[x]);
return set[x];
}
void Union(int a,int b)
{
int ra = find(a);
int rb = find(b);
set[ra] = rb;
}
bool Kruscal()
{
int i,j,k,a,b;
for(i = 1;i <= n;i ++)
set[i] = i;
i = j = ans = 0;
while(i < m && j < n - 1)
{
a = find(edge[i].u);
b = find(edge[i].v);
if(a != b)
{
Union(edge[i].u,edge[i].v);
ans += edge[i].val;
stack[j ++] = i;
}
i ++;
}
for(i = 0;i < n - 1;i ++)
if(edge[stack[i]].sameval == true)
break;
if(i == n - 1)
return true;
memset(flag,false,sizeof(flag));
int sum;
for(i = 0;i < n - 1;i ++)
{
if(edge[stack[i]].sameval == true)
{
flag[stack[i]] = true;
sum = 0;
for(j = 1;j <= n;j ++)
set[j] = j;
j = k = 0;
while(j < m && k < n - 1)
{
if(flag[j] == true)
{
j ++;
continue;
}
a = find(edge[j].u);
b = find(edge[j].v);
if(a != b)
{
Union(edge[j].u,edge[j].v);
sum += edge[j].val;
k ++;
}
j ++;
}
if(k != n - 1)
continue;
if(sum == ans)
return false;
flag[stack[i]] = false;
}
}
return true;
}
int main()
{
int i,t;
scanf("%d",&t);
while(t --)
{
scanf("%d%d",&n,&m);
for(i = 0;i < m;i ++)
{
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val);
edge[i].sameval = false;
}
if(n == 1)
{
printf("0\n");
continue;
}
sort(edge,edge + m,cmp);
for(i = 1;i < m;i ++)
if(edge[i].val == edge[i - 1].val)
{
edge[i - 1].sameval = true;
edge[i].sameval = true;
}
memset(flag,false,sizeof(flag));
if(Kruscal())
printf("%d\n",ans);
else
puts("Not Unique!");
}
return 0;
}
//880K 0MS
/*
7
3 3
1 2 1
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2
7 10
1 2 28
1 4 22
1 6 10
2 3 16
2 7 14
3 4 12
4 5 22
4 7 18
5 6 25
5 7 24
7 12
1 2 6
1 6 6
1 7 6
2 3 2
2 7 3
3 4 3
3 7 2
4 5 1
4 7 4
5 6 8
5 7 3
6 7 7
3 3
1 2 2
2 3 3
3 1 3
3 3
1 2 3
2 3 2
3 1 3
3 2
1 2 2
2 3 2
*/