POJ - 3522 最小生成树
题意:
题目长的变态,其实题意就是给出一个图,若图连通,则求生成树最大边与最小边差值的最小值,输出最小差值。否则输出-1.
题解:
用kruskal算法求最小生成树,要对边先排序。枚举最小边,然后求最小生成树,就可以得到最大边,只要每次更新最优解就行了。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<math.h> 6 #include<vector> 7 #include<queue> 8 #include<stack> 9 #include<map> 10 using namespace std; 11 typedef long long ll; 12 const int maxn=105; 13 const int INF=0x3f3f3f3f; 14 const double eps=1e-8; 15 const double PI=3.1415926; 16 const int mod = 1e9+7; 17 #define mt(A,B) memset(A,B,sizeof(A)) 18 #define lson l,m,rt*2 19 #define rson m+1,r,rt*2+1 20 #define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 21 #define zero(x) (((x)>0?(x):-(x))<eps) 22 int v[maxn]; 23 struct Edge 24 { 25 int u,v,w; 26 }e[maxn*maxn]; 27 bool mmp(Edge x,Edge y) 28 { 29 return x.w<y.w; 30 } 31 int finds(int x) 32 { 33 if(x!=v[x]) 34 { 35 int y=finds(v[x]); 36 v[x]=y; 37 return y; 38 } 39 return x; 40 } 41 int main() 42 { 43 int n,m; 44 while(~scanf("%d%d",&n,&m) && n+m) 45 { 46 for(int i=0;i<m;++i) 47 { 48 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); 49 } 50 sort(e,e+m,mmp); 51 int result=-1; 52 for(int j=0;j<m;++j) 53 { 54 for(int i=1;i<=n;++i) 55 { 56 v[i]=i; 57 } 58 int maxx=0,minn=e[j].w; 59 for(int i=j; i<m; ++i) 60 { 61 int fx=finds(e[i].u); 62 int fy=finds(e[i].v); 63 if(fx!=fy) 64 { 65 v[fx]=fy; 66 maxx=max(maxx,e[i].w); 67 } 68 } 69 int flag=0; 70 for(int i=1; i<=n; ++i) 71 if(v[i]==i) ++flag; 72 if(flag==1 && result==-1) 73 { 74 result=maxx-minn; 75 } 76 else if(flag==1) 77 { 78 result=min(result,maxx-minn); 79 } 80 } 81 printf("%d\n",result); 82 } 83 return 0; 84 }