Given a connected undirected graph, tell if its minimum spanning tree is unique.
Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.
Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.
2 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
3 Not Unique!
题意:如果只有一个最小生成树则输出总权值,若有多个则Not Unique!;(找出最小生成树的个数类似)
思路:和上篇博客差不多,套用Kruskal,只不过套用了两次(这种思路好像不太高效,续更···)
第一遍时找出最小生成树并标记用过的边,然后第二遍中找是否有新的边加入(ans的真假)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int pre1[11000],pre2[11000];
struct node
{
int a;
int b;
int c;
int d;
}s[50100];
bool cmp(node x,node y)
{
if(x.c!=y.c)
return x.c<y.c;
return x.d<y.d;
}
int main()
{
int m,n,r1,r2,i,t;
scanf("%d",&t);
while(t--)
{
memset(s,-1,sizeof(s));
scanf("%d %d",&m,&n);
for(i=1;i<=m;i++)
{
pre1[i]=i;
pre2[i]=i;
}
for(i=0;i<n;i++)
scanf("%d %d %d",&s[i].a,&s[i].b,&s[i].c);
sort(s,s+n,cmp);
int min1=0,min2=0,num=0;
for(i=0;i<n && num<n-1;i++)
{
int r1=s[i].a,r2=s[i].b;
while(r1!=pre1[r1])
r1=pre1[r1];
while(r2!=pre1[r2])
r2=pre1[r2];
if(r1!=r2)
{
pre1[r2]=r1;
min1+=s[i].c;
s[i].d=1;//标记这条边已经用过了;
num++;
}
}
num=0;
bool ans=true;
sort(s,s+n,cmp);
for(i=0;i<n && num<n-1;i++)
{
int r1=s[i].a,r2=s[i].b;
while(r1!=pre2[r1])
r1=pre2[r1];
while(r2!=pre2[r2])
r2=pre2[r2];
if(r1!=r2)
{
pre2[r2]=r1;
min2+=s[i].c;
num++;
if(s[i].d==-1)//如果用到第一次没有用到的边;
ans=false;
}
}
if(min1==min2 && !ans)//总权值相等且用到了不同的边;
printf("Not Unique!\n");
else
printf("%d\n",min1);
}
return 0;
}