題意:ios
給定一個無向帶權圖,判斷這個圖是否有惟一的最小生成樹,若是有輸出最小生成樹,不然輸出Not Unique!算法
分析:spa
模板題,可是對於判斷惟一性,有必定的小技巧,先算出整個圖的最小生成樹,記錄這個最小生成樹的全部邊,而後在整個圖中枚舉把以前最小生成樹刪掉一條邊,再求最小生成樹,一旦出現相同的總權值,就不行了。code
而後Kruskal算法反正很快,我發現最小生成樹的解決方案每每很暴力,2333。很強blog
代碼:string
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 }