poj 3522 kruskal算法活用

题目大意:求生成树上最长边与最短边的差值最小是多少。

解题思路:kruskal+枚举+剪枝。先排序枚举所有的生成树,求最小的。一些基本性质别忘了n个点最少要n-1条边,小于的就没必要求了。一棵生成树如果已经成功添加n-1条边就没必要再算剩下的了可以很好的剪枝。

View Code
 1 #include<iostream>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 struct ss{
6 int x,y,z;
7 }e[5010];
8 int set[105];
9 int find(int x)
10 {
11 while (x!=set[x])
12 x=set[x];
13 return x;
14 }
15 void se(int n)
16 {
17 int i;
18 for (i=1;i<=n;i++)
19 {
20 set[i]=i;
21 }
22 }
23 int Merge(int x,int y)
24 {
25 int a=find(x);
26 int b=find(y);
27 if(a==b)return 0;
28 else set[a]=b;
29 return 1;
30 }
31 int cmp(ss x,ss y)
32 {
33 if(x.z>y.z)return 0;
34 return 1;
35 }
36 int main()
37 {
38 int i,j,k,ans,n,m,min,max,flag;
39 while (cin>>n>>m,n+m)
40 {
41 for (i=1;i<=m;i++)
42 {
43 cin>>e[i].x>>e[i].y>>e[i].z;
44 }
45 if(m<n-1){cout<<"-1"<<endl;continue;}
46 sort(e+1,e+1+m,cmp);
47 ans=100000;
48 for (i=1;i<=m-n+2;i++)
49 {
50 se(n);
51 k=0;
52 max=0;
53 flag=0;
54 min=e[i].z;
55 for (j=i;j<=m;j++)
56 {
57 if (Merge(e[j].x,e[j].y))
58 {
59 k++;
60
61 if(e[j].z>max)max=e[j].z;
62 }
63 if(k==n-1){flag=1;break;}
64 }
65 if (flag)
66 {
67 max-=min;
68 if(max<ans)ans=max;
69 }
70 }
71 if(ans==100000)cout<<"-1"<<endl;
72 else cout<<ans<<endl;
73 }
74 return 0;
75 }
posted @ 2011-08-28 15:41  我们一直在努力  阅读(261)  评论(0编辑  收藏  举报