最小生成树 poj 1679
poj 1679 The Unique MST http://poj.org/problem?id=1679
求最小生成树是否唯一
把构成最小生成树的边一条条的删
#include<iostream> #include<stdio.h> #include<queue> #include<vector> #include<string.h> using namespace std; struct E{ friend bool operator< (E n1, E n2) { return n1.w > n2.w; } int u;int v;int w; }edge[10000]; vector <int > g[102]; priority_queue < E > q; int n,f[102],vis[102]; int find(int a) { return f[a]==a?a:f[a]=find(f[a]); } int klu() { E temp; int ans=0,i,ff,a,b,cnt; for(i=0;i<=n;i++) f[i]=i; for( i=1;i<n;) // 找n-1 个 { temp=q.top (); a=find(temp.u) ; b=find(temp.v) ; if(a!=b) { if(i==n-1) ff=temp.w; else f[a]=b; ans+=temp.w; i++; } q.pop (); } cnt=0; while(!q.empty ()) { temp=q.top(); q.pop (); if(temp.w >ff) break; a=find(temp.u ); b=find(temp.v); if(a!=b) cnt++; if(cnt>0) return -1; } return ans; } void dfs(int s) { vis[s]=1; for(int i=0;i<g[s].size ();i++) if(!vis[g[s][i]]) dfs(g[s][i]); } int main() { int t,m,i,a,b,c,ans; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); edge[i].u=a; edge[i].v=b; edge[i].w=c; q.push(edge[i]); g[a].push_back (b); g[b].push_back (a); } int p=0; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) if(!vis[i]) { dfs(i); p++; } if(p>1) ans=0; else ans=klu(); if(ans==-1) printf("Not Unique!\n"); else printf("%d\n",ans); while(!q.empty ()) q.pop (); for(i=1;i<=n;i++) g[i].clear (); } return 0; }
poj 3522 找最大边-最小边的值最小的 生成树
http://poj.org/problem?id=3522
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 struct node{int x;int y;int w;}no[10002]; 7 8 int minn,f[102]; 9 int cmp(node a,node b) 10 { 11 return a.w<b.w; 12 } 13 int find(int x) 14 { 15 return f[x]==x?x:f[x]=find(f[x]); 16 } 17 int main() 18 { 19 int i,j,a,b,c,aa,bb,maxx=0,num=0,n,m,ans,final; 20 while(scanf("%d%d",&n,&m)) 21 { 22 if(n==0&&m==0) 23 break; 24 for(i=0;i<m;i++) 25 { 26 scanf("%d%d%d",&a,&b,&c); 27 no[i].x=a; 28 no[i].y=b; 29 no[i].w=c; 30 } 31 sort(no,no+m,cmp); 32 final=1000000; 33 for(i=0;i<m;i++) 34 { 35 minn=no[i].w; //枚举最小的 36 ans=0; 37 for(j=1;j<=n;j++) 38 f[j]=j; 39 int k=1; 40 for(j=i;j<m;j++) 41 { 42 aa=find(no[j].x); 43 bb=find(no[j].y); 44 if(aa!=bb) 45 { 46 k++; 47 48 if(no[j].w-minn>ans) 49 ans=no[j].w-minn; 50 if(k==n) 51 break; 52 f[aa]=bb; 53 } 54 } 55 if(j==m) 56 break; 57 if(ans<final) 58 final=ans; 59 } 60 if(final==1000000) 61 printf("-1\n"); 62 else 63 printf("%d\n",final); 64 } 65 return 0; 66 }