poj 3522(最小生成树应用)

题目链接:http://poj.org/problem?id=3522思路:题目要求最小生成树中最大边与最小边的最小差值,由于数据不是很大,我们可以枚举最小生成树的最小边,然后kruskal求最小生成树,直到不能生成生成树为止,然后取最小的差值即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define MAXN 111
 7 #define inf 1<<30
 8 
 9 struct Edge{
10     int u,v;
11     int len;
12 }edge[MAXN*MAXN];
13 int parent[MAXN];
14 int n,m;
15 
16 void Initiate()
17 {
18     for(int i=1;i<=n;i++){
19         parent[i]=i;
20     }
21 }
22 
23 int Find(int x)
24 {
25     if(x==parent[x]){
26         return parent[x];
27     }
28     parent[x]=Find(parent[x]);
29     return parent[x];
30 }
31 
32 void Union(int u,int v)
33 {
34     int r1=Find(u),r2=Find(v);
35     if(r1==r2)return ;
36     parent[r1]=r2;
37 }
38 
39 int cmp(const Edge &p,const Edge &q)
40 {
41     return p.len<q.len;
42 }
43 
44 int Kruskal(int id)
45 {
46     int count=0,MIN=inf,MAX=-inf;
47     for(int i=0;i<m;i++){
48         if(edge[i].len<edge[id].len)continue;
49         int u=edge[i].u,v=edge[i].v;
50         if(Find(u)!=Find(v)){
51             MIN=min(MIN,edge[i].len);
52             MAX=max(MAX,edge[i].len);
53             count++;
54             Union(u,v);
55             if(count==n-1)return MAX-MIN;
56         }
57     }
58     return -1;
59 }
60 
61         
62 
63 int main()
64 {
65     while(~scanf("%d%d",&n,&m)){
66         if(n==0&&m==0)break;
67         for(int i=0;i<m;i++){
68             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].len);
69         }
70         sort(edge,edge+m,cmp);
71         int ans=inf;
72         for(int i=0;i<m;i++){
73             Initiate();
74             int tmp=Kruskal(i);
75             if(tmp==-1)break;
76             ans=min(ans,tmp);
77         }
78         if(ans!=inf){
79             printf("%d\n",ans);
80         }else 
81             printf("-1\n");
82     }
83     return 0;
84 }
View Code

 

posted @ 2013-07-14 14:53  ihge2k  阅读(429)  评论(0编辑  收藏  举报