poj 3522 kruskal算法活用

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

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

ContractedBlock.gif ExpandedBlockStart.gif 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 }

转载于:https://www.cnblogs.com/zhaoguanqin/archive/2011/08/28/2156220.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值