BZOJ 1050: [HAOI2006]旅行comf

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 3380 Solved: 1877

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

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


枚举第一条边的最小生成树

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<set>
const int MAXN=5000+5000;
using namespace std;
int N,M,S,T,temin,mpmax,finalmin,finalmax,minn,fa[MAXN],ff,tt,vv;
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]); 
}
void Union(int x,int y){
    x=find(x);y=find(y);
    if(x==y) return;
    fa[x]=y;
}
int gcd(int x,int y){
    return y==0?x:gcd(y,x%y);
}
vector<pair<int,pair<int,int> > >v;
int main(){
    scanf("%d%d",&N,&M);
    for(register int i=1;i<=M;i++){
        scanf("%d%d%d",&ff,&tt,&vv);
        pair<int,int>p(ff,tt);
        pair<int,pair<int,int> >pp(vv,p);
        v.push_back(pp);
    }
    scanf("%d%d",&S,&T);
    sort(v.begin(),v.end());
    double minn=100000000.0;
    for(register vector<pair<int,pair<int,int> > >::iterator it=v.begin();it!=v.end();it++){
        for(register int i=1;i<=N;i++)fa[i]=i;
        pair<int,pair<int,int> >ppp=*it;
        temin=ppp.first;
        mpmax=0;
        vector<pair<int,pair<int,int> > >::iterator iter=it;
        while(find(S)!=find(T)&&iter!=v.end()){
            pair<int,pair<int,int> >p=*iter;
            Union(p.second.first,p.second.second);
            mpmax=p.first;
            iter++;
        }
        if(find(S)!=find(T)) continue;
        if(minn>(mpmax*1.0/temin)){
            finalmax=mpmax;
            finalmin=temin;
            minn=mpmax*1.0/temin;
        }
    }
    if(minn==100000000.0) printf("IMPOSSIBLE\n");
    else{
        int temp=gcd(finalmax,finalmin);
        finalmax/=temp;finalmin/=temp;
        if(finalmax%finalmin==0){
            printf("%d\n",finalmax/finalmin);
        }else{
            printf("%d/%d\n",finalmax,finalmin);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值