原题
http://poj.org/problem?id=1679
//本题是判断最小生成树是否唯一,可以根据先删除最小生成树里面的边然后新加入一条边,然后判断新生成的最小生成树的权值和原来是否相同
//这就要求要求原来最小生成树里任意两个点之间的最大值。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <iostream>
//#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <vector>
#include <math.h>
#include <set>
using namespace std;
#define INF 999999999
#define N 111
int n,m;
int pre[N],dis[N][N],max1[N][N],g[N];
int vis[N],stack[N];
int sum;
int max(int a,int b){
if(a > b)
return a;
else
return b;
}
int minn(int a,int b){
if(a < b)
return a;
else
return b;
}
void Prime(){
int i,j,k;
memset(vis,0,sizeof(vis));
memset(g,0,sizeof(g));
for(i=1;i<=n;i++){
g[i] = dis[1][i];
pre[i] = 1;
}
vis[1] = 0;
int top=0;
sum = 0;
stack[top++] = 1;
int tmp;
for(i=1;i<=n;i++){
tmp = INF;
for(j=1;j<=n;j++){
if(tmp>g[j] && vis[j]==0){
tmp = g[j];
k = j;
}
}
vis[k] = 1;
if(tmp == INF)
break;
sum+=tmp;
for(j=0;j<top;j++){
max1[stack[j]][k] = max(max1[stack[j]][pre[k]],tmp);//x新加入的点到最小生成树里面每个点的最大距离,前面的代表与这个点相连的那个,后面的代表选择出来的值
}
max1[k][stack[j]] = max1[stack[j]][k];
}
stack[top++] = k;
for(j=1;j<=n;j++){
if(vis[j]==0 && dis[k][j]<g[j]){
g[j] = dis[k][j];
pre[j] = k;
}
}
}
}
int main(){
int T;
int i,j;
int a,b,c;
while(~scanf("%d",&T)){
while(T--){
scanf("%d%d",&n,&m);
for(i=0;i<N;i++){
for(j=0;j<N;j++){
dis[i][j] = INF;
max1[i][j] = 0;
}
}
for(i=0;i<N;i++){
dis[i][i] = 0;
}
for(i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
dis[a][b] = c;
dis[b][a] = c;
}
Prime();
int min = INF;
for(i=1;i<=n;i++){//遍历原最小生成树里面以外的任意边。
for(j=1;j<=n;j++){
if(i!=j && i!=pre[j] && j!=pre[i]){
min = minn(min,dis[i][j]-max1[i][j]);
}
}
}
if(min != 0){
printf("%d\n",sum);
}
else{
printf("Not Unique!\n");
}
}
}
return 0;
}