标签:
题目链接:http://vjudge.net/problem/41567/origin
本来想着m^2的复杂度撑不住,对于这种擦着边的复杂度就好慌。
首先对所有的边排个序,然后枚举每个可以构成生成树的区间(L,R),取区间里面构成树的边的权值的最小和最大的差值,求最小值即可。
如果已经构成生成树可以break掉优化下。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 5005; 7 struct edge 8 { 9 int u,v,w; 10 }; 11 edge e[maxn]; 12 int pre[105]; 13 int Find(int x) 14 { 15 return pre[x]==x?x:pre[x]=Find(pre[x]); 16 } 17 bool cmp(edge A,edge B) 18 { 19 return A.w<B.w; 20 } 21 int main() 22 { 23 int n,m; 24 while(scanf("%d %d",&n,&m)!=EOF&&(n||m)) 25 { 26 for(int i=1;i<=m;i++) 27 { 28 scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w); 29 } 30 sort(e+1,e+m+1,cmp); 31 int count1 = 1; 32 int ans = 20000; 33 for(int i=1;i<=m;i++) 34 { 35 for(int k=1;k<=n;k++) pre[k] = k; 36 count1 = 1; 37 int minv = 20000; 38 int maxv = 0; 39 for(int j=i;j<=m;j++) 40 { 41 int x = Find(e[j].u); 42 int y = Find(e[j].v); 43 if(x!=y) 44 { 45 count1++; 46 pre[x] = y; 47 maxv = max(maxv,e[j].w); 48 minv = min(minv,e[j].w); 49 } 50 if(count1>=n) 51 { 52 break; 53 } 54 } 55 if(count1>=n) 56 { 57 ans = min(ans,maxv-minv); 58 } 59 } 60 if(ans!=20000) printf("%d\n",ans); 61 else printf("-1\n"); 62 } 63 return 0; 64 }
标签:
原文地址:http://www.cnblogs.com/littlepear/p/5979041.html