ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::
  427 随笔 :: 0 文章 :: 15 评论 :: 0 引用

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”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。

枚举每条边作为最小边并求最小生成树得到最大边

#include<cstdio>
#include<algorithm>
struct edge{
    int x,y,v;
};
bool operator<(edge a,edge b){
    return a.v<b.v;
}
edge es[5005];
int f[505];
int n,m,x,y,v,S,T;
int gcd(int a,int b){
    if(!b)return a;
    return gcd(b,a%b);
}
inline int get(int x){
    int a=x,c;
    while(a!=f[a])a=f[a];
    while(a!=(c=f[x]))f[x]=a,x=c;
    return a;
}
int main(){
    int mn=-1,mx;
    double ans=1e10;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d%d",&es[i].x,&es[i].y,&es[i].v);
    }
    scanf("%d%d",&S,&T);
    std::sort(es,es+m);
    for(int i=0;i<m;i++){
        for(int j=0;j<=n;j++)f[j]=j;
        for(int j=i;j<m;j++){
            x=get(es[j].x);
            y=get(es[j].y);
            if(x!=y)f[x]=y;
            if(get(S)==get(T)){
                double s=double(es[j].v)/es[i].v;
                if(s<ans){
                    ans=s;
                    mn=es[i].v;mx=es[j].v;
                }
                break;
            }
        }
    }
    if(~mn){
        int g=gcd(mn,mx);
        mn/=g;mx/=g;
        if(mn>1)printf("%d/%d",mx,mn);
        else printf("%d",mx);
    }else puts("IMPOSSIBLE");
    return 0;
}

 

posted on 2016-02-25 20:33  nul  阅读(79)  评论(0编辑  收藏