Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 14402 | Accepted: 4981 |
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 <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <vector> using namespace std; const long long INF = 1 << 31 -1; int p[11000]; long long mm; long long tmp; int n, m; int fflag; int del; struct edge{ int u; int v; long long w; int flag; }e[10001000]; int find(int x){ return x == p[x] ? x : find(p[x]); } int cmp(edge a, edge b){ return a.w < b.w; } int Kruskal(){ long long ans = 0; int i; for(i = 1; i <= n; i ++) p[i] = i; sort(e + 1, e + m + 1, cmp); for(i = 1; i <= m; i ++){ int x = find(e[i].u); int y = find(e[i].v); if(x != y){ e[i].flag = 1; ans += e[i].w; p[x] = y; } } return ans; } long long Kruskalm(){ long long ans = 0; int i; for(i = 1; i <= n; i ++) p[i] = i; sort(e + 1, e + m + 1, cmp); int j = 0; fflag = 0; for(i = 1; i <= m; i ++){ if(i == del) continue; int x = find(e[i].u); int y = find(e[i].v); if(x != y){ ans += e[i].w; p[x] = y; j ++; } } if(j < n - 1) //如果最后生成树的边数小于n-1,显然就是因为删边之后不连通了,所以这次的结果直接赋为无穷大,相当于不行 ans = INF; return ans; } int main(){ int t, i, tt; cin >> t; while(t --){ int ff = 0; scanf("%d %d", &n ,&m); for(i = 1; i <= m; i ++){ scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w); e[i].flag = 0; } mm = Kruskal(); for(i = 1; i <= m; i ++){ if(e[i].flag){ //tt = e[i].w; del = i; tmp = Kruskalm(); if(tmp == mm){ ff = 1; break; } } } if(ff){ printf("Not Unique!\n"); } else printf("%I64d\n", mm); } return 0; }