标签:lang accept bool pac margin esc ssi ber 最小生成树
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 29079 | Accepted: 10398 |
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!
Source
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int VM=120; 7 const int EM=10010; 8 struct Edge{ 9 int u,v,cap; 10 bool operator < (const Edge& a)const { 11 return cap<a.cap; 12 } 13 }edge[EM<<1]; 14 int n,m,flag,ans,father[VM]; 15 void makeSet(){ 16 for(int i=1;i<=n;i++) 17 father[i]=i; 18 } 19 int findSet(int x){ 20 if(x==father[x]) return x; 21 else return father[x]=findSet(father[x]); 22 } 23 void Kruskal(){ 24 makeSet(); 25 sort(edge,edge+m); 26 int path[EM],cnt=0; 27 ans=0; 28 for(int i=0;i<m;i++){ 29 int u=findSet(edge[i].u); 30 int v=findSet(edge[i].v); 31 if(u!=v){ 32 father[v]=u; ans+=edge[i].cap; 33 path[cnt++]=i; //记录路径 34 } 35 } 36 for(int k=0;k<cnt;k++){ //枚举去掉每一条边 37 makeSet(); 38 int sum=0,j=0; 39 for(int i=0;i<m;i++){ 40 if(i==path[k]) continue; 41 int u=findSet(edge[i].u),v=findSet(edge[i].v); 42 if(u!=v){ 43 father[v]=u; 44 sum+=edge[i].cap; 45 j++; 46 } 47 } 48 if(j==n-1 && sum==ans){ //判断是否能构成树 且 是否与最小生成树相等 49 flag=0;return ; 50 } 51 } 52 } 53 int main(){ 54 int T; 55 scanf("%d",&T); 56 while(T--){ 57 scanf("%d%d",&n,&m); 58 for(int i=0;i<m;i++) 59 scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].cap); 60 flag=1; 61 Kruskal(); 62 if(flag) printf("%d\n",ans); 63 else printf("Not Unique!\n"); 64 } 65 return 0; 66 }
思路:先来一遍最小生成树,此时顺便记录下树边,然后枚举删除掉树边,每次删除后看是否还能生成一棵最小生成树和原最小生成树的MST相等..
标签:lang accept bool pac margin esc ssi ber 最小生成树
原文地址:http://www.cnblogs.com/suishiguang/p/6358712.html