题目链接:http://poj.org/problem?id=1679
就是求是否有多条最小树
跑两次最小树第二次的时候循环一下上一次用过的边不要连这个边看一下次小生成树是否与最小生成树权值一样
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; int n , m , f[110]; int vis[11000]; void init() { for(int i = 0 ; i <= n ; i++) { f[i] = i; } } int find(int x) { if(x == f[x]) return x; int tmp = find(f[x]); return f[x] = tmp; } struct node { int x , y , val; }nodes[11000]; bool cmp(node a , node b) { return a.val < b.val; } int main() { int t , x , y , val; scanf("%d" , &t); while(t--) { scanf("%d%d" , &n , &m); init(); int count = 0; for(int i = 0 ; i < m ; i++) { scanf("%d%d%d" , &x , &y , &val); nodes[count].x = x , nodes[count].y = y , nodes[count].val = val; count++; } int sum = 0 , num = 0; sort(nodes , nodes + count , cmp); bool flag = true; int temp = 0; for(int i = 0 ; i < count ; i++) { int a = find(nodes[i].x) , b = find(nodes[i].y); if(a != b) { f[a] = b; vis[temp++] = i; sum += nodes[i].val; } } int sum2 = 0; for(int i = 0 ; i < temp ; i++) { num = 0 , sum2 = 0; init(); for(int j = 0 ; j < count ; j++) { if(vis[i] != j) { int a = find(nodes[j].x) , b = find(nodes[j].y); if(a != b) { f[a] = b; num++; sum2 += nodes[j].val; } if(num == n - 1) break; } } if(num == n - 1 && sum2 == sum) { flag = false; break; } } if(flag) { printf("%d " , sum); } else { printf("Not Unique! "); } } return 0; }