http://poj.org/problem?id=1679
思路:先生成mst,存储mst的每一条边,然后枚举删除每一条mst中的边,看是否能找出一课次小生成树的权值和最小生成树的权值相等。
如果相等,则不唯一。
1 #include<stdio.h>
2 #include<string.h>
3 #include<algorithm>
4 #define maxn 105
5 #define INF 0xffffff
6 using namespace std;
7 int n,m;
8 int f[maxn];
9 typedef struct
10 {
11 int x,y,w;
12 }Edge;
13 Edge edge[maxn*maxn];
14 int mst[maxn];
15 int find(int x)
16 {
17 while(f[x]>=0)
18 x=f[x];
19 return x;
20 }
21 int cmp(Edge a,Edge b)
22 {
23 return a.w<b.w?1:0;
24 }
25 void make(int a,int b)
26 {
27 if(f[a]<f[b])
28 {
29 f[a]=f[a]+f[b];
30 f[b]=a;
31 }
32 else
33 {
34 f[b]=f[a]+f[b];
35 f[a]=b;
36 }
37 }
38 void kruskal()
39 {
40 int ans=0;
41 int i,j,k=0;
42 for(i=1;i<=m&&k<n-1;i++)
43 {
44 int f1=find(edge[i].x);
45 int f2=find(edge[i].y);
46 if(f1!=f2)
47 {
48 make(f1,f2);
49 k++;
50 ans+=edge[i].w;
51 mst[k]=i;
52 }
53 }
54 for(i=1;i<=n-1;i++)
55 {
56 int ans2=0,k2=0;
57 memset(f,-1,sizeof(f));
58 for(j=1;j<=m;j++)
59 {
60 if(j==mst[i])
61 continue;
62 int f1=find(edge[j].x);
63 int f2=find(edge[j].y);
64 if(f1!=f2)
65 {
66 make(f1,f2);
67 k2++;
68 ans2+=edge[j].w;
69 }
70 }
71 if(k2!=n-1)
72 continue;
73 if(ans==ans2)
74 {
75 printf("Not Unique!
");
76 return;
77 }
78 }
79 printf("%d
",ans);
80 }
81 int main()
82 {
83 // freopen("in.txt","r",stdin);
84 int ca;
85 scanf("%d",&ca);
86 while(ca--)
87 {
88 memset(edge,0,sizeof(edge));
89 scanf("%d%d",&n,&m);
90 memset(f,-1,sizeof(f));
91 memset(mst,0,sizeof(mst));
92 int i;
93 for(i=1;i<=m;i++)
94 scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].w);
95 sort(edge+1,edge+m+1,cmp);
96 kruskal();
97 }
98 return 0;
99 }