(最小生成树唯一性)POJ 1679 - The Unique MST
题意:
给定一个无向带权图,判断这个图是否有唯一的最小生成树,如果有输出最小生成树,否则输出Not Unique!
分析:
模板题,但是对于判断唯一性,有一定的小技巧,先算出整个图的最小生成树,记录这个最小生成树的所有边,然后在整个图中枚举把之前最小生成树删掉一条边,再求最小生成树,一旦出现相同的总权值,就不行了。
然后Kruskal算法反正很快,我发现最小生成树的解决方案往往很暴力,2333。很强
代码:
1 #include <set> 2 #include <map> 3 #include <list> 4 #include <cmath> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <string> 10 #include <cctype> 11 #include <cstdio> 12 #include <cstring> 13 #include <cstdlib> 14 #include <iostream> 15 #include <algorithm> 16 // #include <unordered_map> 17 18 using namespace std; 19 20 typedef long long ll; 21 typedef unsigned long long ull; 22 typedef pair<int, int> pii; 23 typedef pair<ull, ull> puu; 24 25 #define inf (0x3f3f3f3f) 26 #define lnf (0x3f3f3f3f3f3f3f3f) 27 #define eps (1e-9) 28 #define fi first 29 #define se second 30 31 bool sgn(double a, string select, double b) { 32 if(select == "==")return fabs(a - b) < eps; 33 if(select == "!=")return fabs(a - b) > eps; 34 if(select == "<")return a - b < -eps; 35 if(select == "<=")return a - b < eps; 36 if(select == ">")return a - b > eps; 37 if(select == ">=")return a - b > -eps; 38 } 39 40 41 //-------------------------- 42 43 const ll mod = 1000000007; 44 const int maxn = 110; 45 46 47 int n,m; 48 49 int par[maxn]; 50 51 struct Edge { 52 int u,v,w; 53 } edge[maxn*maxn]; 54 55 vector<int> mstedge; 56 57 bool cmp(Edge a,Edge b) { 58 return a.w<b.w; 59 } 60 61 int findx(int x) { 62 if(par[x]==x)return x; 63 else return par[x]=findx(par[x]); 64 } 65 66 67 int Kruskal(int n,int x) { 68 for(int i=1; i<=n; i++) { 69 par[i]=i; 70 } 71 int cnt=0; 72 int ans=0; 73 for(int i=0; i<m; i++) { 74 if(i==x)continue; 75 int u = edge[i].u; 76 int v = edge[i].v; 77 int w = edge[i].w; 78 int t1 = findx(u); 79 int t2 = findx(v); 80 if(t1!=t2) { 81 ans+=w; 82 par[t1]=t2; 83 cnt++; 84 if(x==-1)mstedge.push_back(i); 85 } 86 if(cnt==n-1)break; 87 } 88 if(cnt<n-1)return -1; 89 else return ans; 90 } 91 92 void solve() { 93 int t; 94 scanf("%d",&t); 95 while(t--) { 96 memset(edge,0,sizeof(edge)); 97 mstedge.clear(); 98 scanf("%d%d",&n,&m); 99 for(int i=0; i<m; i++) { 100 scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); 101 } 102 sort(edge,edge+m,cmp); 103 int res = Kruskal(n,-1); 104 // printf("res=%d\n",res); 105 bool same = false; 106 for(int i=0; i<mstedge.size(); i++) { 107 int rr = Kruskal(n,mstedge[i]); 108 // printf("rr=%d\n",rr); 109 if(rr==res) { 110 puts("Not Unique!"); 111 same=true; 112 break; 113 } 114 } 115 if(!same) { 116 printf("%d\n",res); 117 } 118 } 119 } 120 121 int main() { 122 123 #ifndef ONLINE_JUDGE 124 freopen("1.in", "r", stdin); 125 // freopen("1.out", "w", stdout); 126 #endif 127 // iostream::sync_with_stdio(false); 128 solve(); 129 return 0; 130 }