题意:问你最小生成树的长度是不是唯一,如果是唯一,就输出最小生成树的长度,否则输出“Not Unique!”。
看次小生成树和最小生成树的长度是不是一样的即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=20000;
int pre[maxn];
int n,m;
int findd(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
int i=x,j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void join(int x,int y)
{
int tx,ty;
tx=findd(x);
ty=findd(y);
if(tx!=ty)
{
pre[ty]=tx;
}
}
struct node
{
int u,v,w;
bool select;
}edge[maxn*4+100];
bool cmp(node a,node b)
{
if(a.w!=b.w)
return a.w<b.w;
if(a.u!=b.u)
return a.u<b.u;
return a.v<b.v;
}
struct node1
{
int v,nxt;
}link[maxn*3+100];
int len[maxn][maxn];
int cnt=0;
int head[maxn],end[maxn];
void kruskal()
{
memset(head,-1,sizeof(head));
cnt=0;
int kk=0;
for(int i=0;i<n;i++)
{
link[i].v=i+1;
link[i].nxt=head[i+1];
head[i+1]=i;
end[i+1]=i;
}
sort(edge+1,edge+1+m,cmp);
// printf("%d\n",m);
for(int i=1;i<=m;i++)
{
if(kk==n-1)
{
break;
}
// printf("1111111");
if(edge[i].w<0)
continue;
int x,y;
x=findd(edge[i].u);
y=findd(edge[i].v);
//printf(":%d %d\n",x,y);
if(x!=y)
{
for(int j=head[x];j!=-1;j=link[j].nxt)
{
for(int k=head[y];k!=-1;k=link[k].nxt)
{
len[link[j].v][link[k].v]=len[link[k].v][link[j].v]=edge[i].w;
}
}
join(x,y);
link[end[y]].nxt=head[x];
end[y]=end[x];
kk++;
edge[i].select=true;
}
}
}
int main ()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
pre[i]=i;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
edge[i].select=false;
}
kruskal();
int mst=0;
int minn=0x3f3f3f3f;
for(int i=1;i<=m;i++)
{
if(edge[i].select==true)
{
mst+=edge[i].w;
}
}
//printf("%d\n",mst);
for(int i=1;i<=m;i++)
{
if(edge[i].select==false)
minn=min(minn,mst+edge[i].w-len[edge[i].u][edge[i].v]);
}
if(minn==mst)
printf("Not Unique!\n");
else
printf("%d\n",mst);
}
}