苗条生成树Slim Span 与舒适的路线——刘汝佳的最小极差生成树(至少我第一次看到这种方法是从刘汝佳那里学来的)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了苗条生成树Slim Span 与舒适的路线——刘汝佳的最小极差生成树(至少我第一次看到这种方法是从刘汝佳那里学来的)相关的知识,希望对你有一定的参考价值。

  昨天做的Slim Span,今天做了舒适的路线,都是差不多的题目。舒适的路线因为一些小瑕疵调了一会答案储存与输出。

  Slim Span:

技术分享
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<vector>
 5 using namespace std;
 6 const int N=128;
 7 struct node{
 8     int x,y,v;
 9     bool operator < (node oth)const{return v<oth.v;}
10 };
11 int n,m;
12 int fth[N],res=0x7fffffff;
13 int fnd(int x){return (fth[x]==x?x:fth[x]=fnd(fth[x]));}
14 bool uni(int x,int y){
15     int u=fnd(x),v=fnd(y);
16     if(u!=v){
17         fth[u]=v;
18         return true;
19     }
20     return false;
21 }
22 int main(){
23     while(cin>>n>>m&&(n||m)){
24         res=0x7fffffff;
25         vector<node> e;
26         for(int i=1;i<=m;i++){
27             int x,y,z;cin>>x>>y>>z;
28             e.push_back((node){x,y,z});
29         }
30         sort(e.begin(),e.end());
31         for(int i=0;i<e.size();i++){
32             int cnt=0;
33             for(int j=0;j<N;j++)fth[j]=j;
34             for(int j=i;j<e.size();j++)
35                 if(uni(e[j].x,e[j].y)){
36                     cnt++;
37                     if(cnt==n-1){
38                         res=min(res,e[j].v-e[i].v);
39                         break;
40                     }
41                 }
42         }
43         cout<<(res!=0x7fffffff?res:-1)<<endl;
44     }
45     return 0;
46 }
Problem_01

  Virtual Judge POJ 3522 版本 329ms

  舒适的路线:

技术分享
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<vector>
 5 using namespace std;
 6 const int N=512;
 7 struct node{
 8     int x,y,v;
 9     bool operator < (const node oth) const {return v<oth.v;}
10 };
11 int n,m,sx,tx;
12 int fth[N];
13 vector<node> e,ans;//从sort 方式不一样可以看出,ans 和e 虽然用了相同的结构体,但其实储存的
14                    //不是同种元素。e 是边,xyv 是起点终点和边权。而ans 其实是我偷懒没有定义
15                    //新结构,它储存的是使得sx 到tx 有路径的联通方案的最大边与最小边的
16                    //约分后长度。
17 bool cmp(node l,node r){
18     return l.x*r.y<r.x*l.y;
19 }
20 int fnd(int x){return (fth[x]==x?x:fth[x]=fnd(fth[x]));}
21 void uni(int x,int y){
22     int u=fnd(x),v=fnd(y);
23     if(u!=v)fth[u]=v;
24 }
25 int gcd(int x,int y){return (y==0?x:gcd(y,x%y));}
26 int main(){
27     cin>>n>>m;
28     for(int i=1;i<=m;i++){
29         int x,y,z;cin>>x>>y>>z;
30         e.push_back((node){x,y,z});
31     }
32     cin>>sx>>tx;
33     sort(e.begin(),e.end());
34     for(int i=0;i<e.size();i++){
35         for(int j=0;j<N;j++)fth[j]=j;
36         for(int j=i;j<e.size();j++){
37             uni(e[j].x,e[j].y);
38             if(fnd(sx)==fnd(tx)){
39                 int t=gcd(e[i].v,e[j].v);
40                 int fx=e[j].v/t,fy=e[i].v/t;
41                 ans.push_back((node){fx,fy,0});
42                 break;
43             }
44         }
45     }
46     if(!ans.size())cout<<"IMPOSSIBLE"<<endl;
47     else{
48         sort(ans.begin(),ans.end(),cmp);
49         if(ans[0].y!=1)cout<<ans[0].x<<"/"<<ans[0].y<<endl;
50         else cout<<ans[0].x<<endl;
51     }
52     return 0;
53 }
Problem_02

  CodeVS 1007ms

以上是关于苗条生成树Slim Span 与舒适的路线——刘汝佳的最小极差生成树(至少我第一次看到这种方法是从刘汝佳那里学来的)的主要内容,如果未能解决你的问题,请参考以下文章

uva_1935_Slim Span

uvalive 3887 Slim Span

UVa 1395 - Slim Span(最小生成树变形)

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

POJ-3522 Slim Span(最小生成树)

UVa 1395 Slim Span (最小生成树)