求次小生成树
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000+10;
const int INF=1000000;
int vis[maxn],pre[maxn],dis[maxn];
int G[maxn][maxn],path[maxn][maxn],use[maxn][maxn];
int prime(int n)
{
int ans=0;
memset(vis,0,sizeof(vis));
vis[1]=1;
for(int i=1;i<=n;i++)
{
pre[i]=1;
dis[i]=G[1][i];
}
for(int i=1;i<n;i++)
{
int minn=INF,k=-1;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]<minn)
{
minn=dis[k=j];
}
vis[k]=1;
use[pre[k]][k]=use[k][pre[k]]=1;
ans+=minn;
for(int j=1;j<=n;j++)
{
if(vis[j]&&k!=j)
path[k][j]=path[j][k]=max(path[pre[j]][j],minn);
if(!vis[j]&&dis[j]>G[k][j])
dis[j]=G[k][j],pre[j]=k;
}
}
return ans;
}
bool ok(int n)
{
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(!use[i][j]&&path[i][j]==G[i][j])
return false;
}
return true;
}
void init(int n)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
path[i][j]=0;
G[i][j]=i==j?0:INF;
use[i][j]=0;
}
}
}
int main()
{
int t,n,m,x,y,w;
//freopen("K.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
init(n);
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&w);
G[x][y]=G[y][x]=w;
}
int ans=prime(n);
if(ok(n))
printf("%d\n",ans);
else
printf("Not Unique!\n");
}
return 0;
}