1 /*
2 题意:求次小生成树,权值和相同则输出字符串,否则输出值
3
4 题解:先求出最小生成树,然后枚举删除最小生成树的每一条边,找出新的最小生成树,即次小生成树,求出其中权值和最
5 小的一棵树,即可求解
6 */
7 #include <cstdio>
8 #include <stdlib.h>
9
10 struct edge
11 {
12 int u,v;
13 bool flag;
14 int w;
15 }E[5005];
16 int n,m;
17 int set[105];
18
19
20 int cmp(const void *a,const void *b)
21 {
22 edge *c,*d;
23 c = (struct edge *)a;
24 d = (struct edge *)b;
25 return c->w-d->w;
26 }
27
28 int find(int r)
29 {
30 while (set[r] != r)
31 r = set[r];
32 return set[r];
33 }
34
35 int Kruskal(int rm_edge)
36 {
37 int i;
38 int f1,f2;
39 int count=1;
40 int ret = 0;
41 for(i=0;i<m;i++)
42 {
43 if(count == n)
44 break;
45 if(i == rm_edge) // 遇见选择删除的边则跳过
46 continue;
47 f1 = find(E[i].u);
48 f2 = find(E[i].v);
49 if(f1 == f2)
50 continue;
51 set[f1] = f2;
52 E[i].flag=true;
53 ret += E[i].w;
54 count++;
55 }
56 return ret;
57 }
58
59 int main(void)
60 {
61 int T;
62 int z,i;
63 int a,b,c;
64 int del[105],k;
65
66 scanf("%d",&T);
67 while(T--)
68 {
69 scanf("%d%d",&n,&m);
70 // 第一次先找出最小生成树
71 for(int i=1; i<=n; i++)
72 set[i] = i;
73 for(i=0;i<m;i++)
74 {
75 scanf("%d%d%d",&a,&b,&c);
76 E[i].u=a;
77 E[i].v=b;
78 E[i].w=c;
79 E[i].flag = false;
80 }
81
82 qsort(E,m,sizeof(E[0]),cmp);
83 int ans = Kruskal(-1);
84 int temp=0;
85 for(i=1; i<=n; i++)
86 if(set[i]==i)
87 temp++;
88 if(temp>1)
89 {
90 printf("0\n");
91 continue;
92 }
93 k=0;
94 for(i=0;i<m;i++)
95 if(E[i].flag)
96 del[k++]=i;
97
98 bool flag = false;
99 for(z=0;z<k;z++)
100 {
101 for(int i=1; i<=n; i++)
102 set[i] = i;
103 int tmp = Kruskal(del[z]); // 依次删除最小生成树的边来再次生成树
104 temp = 0;
105 for(i=1; i<=n; i++)
106 if(set[i] == i)
107 temp++;
108 if(temp > 1)
109 continue;
110
111 if(tmp == ans)
112 {
113 flag=true;
114 break;
115 }
116 }
117
118 if(flag)
119 printf("Not Unique!\n");
120 else
121 printf("%d\n",ans);
122 }
123 return 0;
124 }