Description
Input
Output
Sample Input
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
Sample Output
3
Not Unique!
次小生成树与最小生成树一样即不唯一,注意判断原图为一棵树的情况。
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#define nn 110
#define mm 20010
using namespace std;
int mst=0,e=0,n,m,fa[nn],fir[nn],nxt[mm],to[mm],w[mm],f[nn][nn];
bool vis[nn];
int read()
{
	int ans=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();}
	while(isdigit(ch)) {ans=ans*10+ch-‘0‘;ch=getchar();}
	return ans*f;
}
struct bb{
	int fro,to,w;
	bool use;
}g[mm];
int find(int x)
{
	return fa[x]==x? x:fa[x]=fa[fa[x]];
}
void add(int a,int b,int ww)
{
	nxt[++e]=fir[a];fir[a]=e;to[e]=b;w[e]=ww;
	nxt[++e]=fir[b];fir[b]=e;to[e]=a;w[e]=ww;
}
void kruskal()
{
	int sum=0;e=0;mst=0;
	for(int i=1;i<=n;i++)
	  fa[i]=i;	
	memset(fir,0,sizeof(fir));
    memset(nxt,0,sizeof(nxt));
	for(int i=1;i<=m;i++)
	  if(find(g[i].fro)!=find(g[i].to))
	  {
	  	fa[fa[g[i].fro]]=fa[g[i].to];
	  	add(g[i].fro,g[i].to,g[i].w);
	  	mst+=g[i].w;
		g[i].use=1;           ///////
	  	if(++sum==n-1)
	  	  break;
	  }
}
void dfs(int o,int s)
{
	vis[o]=1;
	for(int i=fir[o];i;i=nxt[i])
	  if(!vis[to[i]])
	  {
	  	f[s][to[i]]=max(f[s][o],w[i]);
	  	dfs(to[i],s);
	  }
}
void les()
{
	int more=0,cha=100000000;
	for(int i=1;i<=m;i++)
	  if(!g[i].use)
	  {
	  	more++;
	  	cha=min(cha,g[i].w-f[g[i].fro][g[i].to]);
	  }
	if(!more)
	  printf("%d\n",mst);
	else if(!cha)
	  printf("Not Unique!\n");
	else
	  printf("%d\n",mst);
}
int main()
{
	int t;
	t=read();
	while(t--)
	{
		n=read();m=read();
		for(int i=1;i<=m;i++)
		{
			g[i].fro=read();g[i].to=read();g[i].w=read();g[i].use=0;
		}
		kruskal();
		for(int i=2;i<=n;i++)
	      vis[i]=0;
	    for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
	          vis[j]=0;
	        dfs(i,i);
		}
		les();
	}
	return 0;
}
 原文:http://www.cnblogs.com/charlotte-o/p/7577322.html