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