BZOJ1050: [HAOI2006]旅行comf
Description
给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。
Input
第一行包含两个正整数,N和M。 下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
Output
如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
Sample Input
【样例输入1】
4 2
1 2 1
3 4 2
1 4
【样例输入2】
3 3
1 2 10
1 2 5
2 3 8
1 3
【样例输入3】
3 2
1 2 2
2 3 4
1 3
4 2
1 2 1
3 4 2
1 4
【样例输入2】
3 3
1 2 10
1 2 5
2 3 8
1 3
【样例输入3】
3 2
1 2 2
2 3 4
1 3
Sample Output
【样例输出1】
IMPOSSIBLE
【样例输出2】
5/4
【样例输出3】
2
【数据范围】
1< N < = 500
1 < = x, y < = N,0 < v < 30000,x ≠ y
0 < M < =5000
IMPOSSIBLE
【样例输出2】
5/4
【样例输出3】
2
【数据范围】
1< N < = 500
1 < = x, y < = N,0 < v < 30000,x ≠ y
0 < M < =5000
题解:
根据题目我们可以采用kruskral的思想,按速度从大到小(从小到大也可以)加边,用并查集来判断s点和t点是否连通,
因为速度我们是排序过的(这点很重要,在很多题中都有运用),所以我们按顺序加边的时候最先联通的时候,比值一定比后面的小,
因为差距最小,不断更新答案就可以求出。(并且保证最优解一定会被更新)
代码(打的丑,别打我):
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 struct edge{ 8 int x,y,w; 9 }a[5010]; 10 int fa[510]; 11 bool cmp(const edge&x,const edge&y){ 12 return x.w>y.w; 13 } 14 int gcd(int a,int b){ 15 if (b==0) return a; 16 else return(gcd(b,a%b)); 17 } 18 int find(int a){ 19 if(fa[a]!=a) fa[a]=find(fa[a]); 20 return fa[a]; 21 } 22 int main (){ 23 int n,m,s,t,flag=0,xi,yi,flag2=1; 24 scanf("%d %d",&n,&m); 25 for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); 26 scanf("%d%d",&s,&t); 27 sort(a+1,a+m+1,cmp); 28 for(int i=1;i<=m;i++){ 29 for(int k=1;k<=n;k++) fa[k]=k; 30 for(int j=i;j<=m;j++){ 31 fa[find(a[j].x)]=find(a[j].y); 32 if(find(s)==find(t)){ 33 flag++; 34 if(flag==1) { 35 xi=a[i].w; 36 yi=a[j].w; 37 } 38 else{ 39 if(a[i].w*yi<xi*a[j].w){ 40 xi=a[i].w; 41 yi=a[j].w; 42 break; 43 } 44 } 45 } 46 } 47 } 48 if(flag==0) cout<<"IMPOSSIBLE"<<endl; 49 else{ 50 if(gcd(xi,yi)==yi) printf("%d",xi/yi); 51 else printf("%d/%d",xi/gcd(xi,yi),yi/gcd(xi,yi)); 52 } 53 }
by:排序之后加边,可以保证一旦更新,既是最优解,类似的有道题是用floyd。。。