[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不可能相同。

1<N<=500,1<=x,y<=N,0<v<30000,0<M<=5000

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

Sample Output

【样例输出1】
IMPOSSIBLE
【样例输出2】
5/4
【样例输出3】
2

Solution

对边排序然后暴力枚举最小边最大边,并查集判联通就行了。

#include<bits/stdc++.h>
using namespace std;
 
void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
 
void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

const int maxn = 2e5+10;

#define lf double
const lf inf = 1e9;

int n,m,s,t,fa[maxn],a,b;
struct edge{
	int u,v,w;
	int operator < (const edge &rhs) const {return w<rhs.w;}
}e[maxn];

int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}

int main() {
	read(n),read(m);
	for(int i=1;i<=m;i++) read(e[i].u),read(e[i].v),read(e[i].w);
	read(s),read(t),sort(e+1,e+m+1);
	lf ans=inf;
	for(int i=1;i<=m;i++) {
		for(int k=1;k<=n;k++) fa[k]=k;
		for(int j=i;j<=m;j++) {
			int u=find(e[j].u),v=find(e[j].v);
			if(u!=v) fa[u]=v;
			if(find(s)==find(t)) {
				if((lf)e[j].w/e[i].w<ans)
					ans=(lf)e[j].w/e[i].w,a=e[j].w,b=e[i].w;
				break;
			}
		}
	}
	if(ans==inf) puts("IMPOSSIBLE");
	else {
		int t=__gcd(a,b);a/=t,b/=t;
		if(b==1) printf("%d\n",a);
		else printf("%d/%d\n",a,b);
	}
	return 0;
}
posted @ 2019-02-16 15:07  Hyscere  阅读(28)  评论(0编辑  收藏