求最小生成树是否唯一。若唯一,输出值,否则输出 not unique。
判断是否唯一MST中心思想:查找到当前的最优合并项后,判断是否有等效的未合并项。
复杂度O(v
2).
prim 的应用:在加入一点时,判断该点是否有多种最短路径连接到已完成的图。
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define mx 110
#define inf 0xffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define debug puts("------------------------")
int a[mx][mx];
int n,m;
int flag;
int cnt[mx],len[mx],vis[mx];
int prim()
{
int res=0,pos=1;
flag=0;
mem(vis,0);
mem(cnt,0);
vis[pos]=1;
for(int i=2;i<=n;i++)
len[i]=a[i][1];
for(int ii=1;ii<n;ii++)
{
int mi=inf;
int t;
for(int i=1;i<=n;i++)
if(!vis[i]&&len[i]<mi)
mi=len[i],t=i;
if(cnt[t]!=0)
{
flag=1;
break;
}
vis[t]=1;
pos=t;
res+=len[t];
for(int i=1;i<=n;i++)
{
if(!vis[i]&&a[i][pos]<len[i])
len[i]=a[i][pos],cnt[i]=0;
else if(!vis[i]&&a[i][pos]==len[i])
cnt[i]++;
}
}
return res;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
int x,b,c;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
a[i][j]=inf;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&b,&c);
a[x][b]=a[b][x]=c;
}
int ans=prim();
if(flag)puts("Not Unique!");
else printf("%d\n",ans);
}
}