BZOJ 1050 [HAOI2006]旅行comf
1050: [HAOI2006]旅行comf
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 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
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
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 }