BZOJ 1050 [HAOI2006]旅行comf

1050: [HAOI2006]旅行comf

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1889  Solved: 976
[Submit][Status][Discuss]

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

Sample Output

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

HINT

 

【数据范围】

1<  N < = 500

1 < = x, y < = N,0 < v < 30000,x ≠ y

0 < M < =5000

 

Source

题解:奇妙的题啊。。。看到边数只有5000,又给了10sec,那就应该是枚举边区间咯?这很简单啊。。。

可以理解成:"起跑线不同的最小生成树运动员们要争分数最小。。。"。。。。。。

有个小trick:分数更新的时候不用乘法哦。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stack>
 6 #include<queue>
 7 #include<cstring>
 8 #define PAU putchar(' ')
 9 #define ENT putchar('\n')
10 using namespace std;
11 const int maxn=500+10,maxm=10000+10,inf=1e9;
12 struct edge{int x,y,w;}e[maxm];bool operator<(const edge&a,const edge&b){return a.w<b.w;}
13 int n,m,fa[maxn];
14 int findset(int x){return x==fa[x]?x:fa[x]=findset(fa[x]);}
15 inline int read(){
16     int x=0;bool sig=1;char ch=getchar();
17     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0;
18     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
19     return sig?x:-x;
20 }
21 inline void write(long long x){
22     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
23     int len=0;static long long buf[20];while(x)buf[len++]=x%10,x/=10;
24     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
25 }
26 long long gcd(long long a,long long b){return !b?a:gcd(b,a%b);}
27 int S,T;
28 int main(){
29     n=read();m=read();int x,y;long long son=inf,mother=1;
30     for(int i=1;i<=m;i++)x=read(),y=read(),e[i]=(edge){x,y,read()};
31     S=read();T=read();sort(e+1,e+m+1);
32     for(int i=1;i<m;i++){
33         for(int j=1;j<=n;j++)fa[j]=j;
34         for(int j=i;j<=m;j++){
35             x=findset(e[j].x);y=findset(e[j].y);fa[x]=y;
36             if(findset(S)==findset(T)){
37                 if(e[j].w*mother<e[i].w*son)mother=e[i].w,son=e[j].w;break;
38             }if(e[j].w*mother>=e[i].w*son)break;
39         }
40     }if(son==inf){puts("IMPOSSIBLE");return 0;}
41     long long t=gcd(son,mother);son/=t;mother/=t;
42     if(mother==1)write(son);
43     else write(son),putchar('/'),write(mother);
44     return 0;
45 }

 

posted @ 2015-08-14 21:57  AI_Believer  阅读(280)  评论(0编辑  收藏  举报