苗条生成树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

时间: 2024-10-25 14:18:23

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

POJ 3522 Slim Span (Kruskal +枚举 边权差最小的生成树)

Slim Span Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6685 Accepted: 3544 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E), where V is a

poj 3522 Slim Span 最大边减最小边最小的生成树

枚举最小边进行kruskal. #include <cstdio> #include <algorithm> using namespace std; #define maxn 120 #define maxm 10000 struct edge { int u,v,w; }e[maxm]; int p[maxn],n,m; int find(int x) { if(x==p[x]) return x; return p[x]=find(p[x]); } void link(int

【UVA 1395】 Slim Span (苗条树)

[题意] 求一颗生成树,满足最大边和最小边之差最小 InputThe input consists of multiple datasets, followed by a line containing two zeros separated by a space.Each dataset has the following format.n ma1 b1 w1...am bm wmEvery input item in a dataset is a non-negative integer.

UVA1395 Slim Span(kruskal算法)

Slim Span [PDF Link] Given an undirected weighted graph G , you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E) , where V is a set of vertices {v1, v2,..., vn} and E is a set of undirected edges {e1, e2,.

【Kruskal】Slim Span

[Uva1395]Slim Span 题目略…… 试题分析:codevs1001舒适的路线上加一个判一下连通性就好,顺便把除改成减 代码: #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; inline int read(){ int x=0,f=1;char c=getchar(); for(;!isdigit(c);

UVALive-3887 Slim Span (kruskal)

题目大意:定义无向图生成树的最大边与最小边的差为苗条度,找出苗条度最小的生成树的苗条度. 题目分析:先将所有边按权值从小到大排序,在连续区间[L,R]中的边如果能构成一棵生成树,那么这棵树一定有最小的苗条度.枚举所有这样的区间. 代码如下: # include<iostream> # include<cstdio> # include<set> # include<queue> # include<cstring> # include<al

UVA 1395 - Slim Span(MST)

UVA 1395 - Slim Span 题目链接 题意:给定一些结点和边,要求出最苗条度最小的生成树,苗条度定义为:生成树中最大权的边减去最小权的边的值 思路:类似建最小生成树的算法,多一步枚举起始边即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 105; const int INF = 0x3f3f3f3f; int

UVA1395 Slim Span(kruskal)

题目:Slim Span UVA 1395 题意:给出一副无向有权图,求生成树中最小的苗条度(最大权值减最小权值),如果不能生成树,就输出-1: 思路:将所有的边按权值有小到大排序,然后枚举每一条边,以这条边开始利用Kruskal算法生成树,生成过程中求出权值的最大值,这个最大值减去当前枚举的边的权值就是苗条度,再动态维护一下最小苗条度就可以了. #include <iostream> #include <algorithm> #include <queue> #inc

POJ 3522 ——Slim Span——————【最小生成树、最大边与最小边最小】

Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7102   Accepted: 3761 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E), where V