POJ 3552 Slim Span (最小差值生成树)

链接:http://poj.org/problem?id=3522

题意:给你N个点,M条边(无向的);让你求一个生成树它具有:最大边权与最小边权的差是最小的。

分析:使用kru算法求生成树;当我们用最小边求取了生成树后,去除最小边,继续再求生成树,只需要每次求完生成树后跟新答案就可以了;复杂度O(M*M),因为边不多,可以实现。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #include<algorithm>
 5 #include<cstring>
 6 using namespace std;
 7 #define ll long long
 8 #define ull unsigned long long
 9 #define mems(a,b) memset(a,b,sizeof(a))
10 const int maxn=1e5+10;
11 const int inff=1e9+7;
12 int N,M;
13 int fa[maxn],pos[maxn];
14 struct EDGE{
15     int st,en,len;
16     bool operator<(const EDGE &a)const{
17         return len<a.len;
18     }
19 }edge[maxn];
20 
21 int find_(int x){
22     if(x==fa[x])
23         return x;
24     fa[x]=find_(fa[x]);
25     return fa[x];
26 }
27 
28 int kru(){
29     int ans=inff;
30     for(int k=1;k<=M;k++){
31         int cnt=0;
32         int temp=inff;
33         for(int i=1;i<=N;i++)
34             fa[i]=i;
35         for(int i=k;i<=M;i++){
36             int x=find_(edge[i].st);
37             int y=find_(edge[i].en);
38             int len=edge[i].len;
39             if(x!=y){
40                 fa[x]=y;
41                 cnt++;
42                 if(cnt==N-1){
43                     temp=len-edge[k].len;
44                     break;
45                 }
46             }
47         }
48         ans=min(ans,temp);
49     }
50     if(ans==inff)
51         ans=-1;
52     return ans;
53 }
54 
55 int main()
56 {
57     while(scanf("%d%d",&N,&M)&&(N+M)){
58     for(int i=1;i<=M;i++){
59         scanf("%d%d%d",&edge[i].st,&edge[i].en,&edge[i].len);
60     }
61     sort(edge+1,edge+1+M);
62 
63     printf("%d\n",kru());
64     }
65     return 0;
66 }
代码
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #include<algorithm>
 5 #include<cstring>
 6 using namespace std;
 7 #define ll long long
 8 #define ull unsigned long long
 9 #define mems(a,b) memset(a,b,sizeof(a))
10 const int maxn=1e5+10;
11 const int inff=1e9+7;
12 int N,M;
13 int fa[maxn];
14 struct EDGE{
15     int st,en,len;
16     bool operator<(const EDGE &a)const{
17         return len<a.len;
18     }
19 }edge[maxn];
20 
21 int find_(int x){
22     if(x==fa[x])
23         return x;
24     fa[x]=find_(fa[x]);
25     return fa[x];
26 }
27 
28 int kru(){
29     int ans=inff;
30     for(int k=1;k<=M;k++){
31         int cnt=0;
32         int temp=inff;
33         for(int i=1;i<=N;i++)
34             fa[i]=i;
35         for(int i=k;i<=M;i++){
36             int x=find_(edge[i].st);
37             int y=find_(edge[i].en);
38             int len=edge[i].len;
39             if(x!=y){
40                 fa[x]=y;
41                 cnt++;
42                 if(cnt==N-1){
43                     temp=len-edge[k].len;
44                     break;
45                 }
46             }
47         }
48         ans=min(ans,temp);
49     }
50     if(ans==inff)
51         ans=-1;
52     return ans;
53 }
54 
55 int main()
56 {
57     while(scanf("%d%d",&N,&M)&&(N+M)){
58     for(int i=1;i<=M;i++){
59         scanf("%d%d%d",&edge[i].st,&edge[i].en,&edge[i].len);
60     }
61     sort(edge+1,edge+1+M);
62 
63     printf("%d\n",kru());
64     }
65     return 0;
66 }

猜你喜欢

转载自www.cnblogs.com/Y-Meng/p/9282999.html