codevs1001 舒适的路线

1001 舒适的路线

 

2006年

 时间限制: 2 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述 Description

Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。
Z小镇附近共有
N(1<N≤500)个景点(编号为1,2,3,…,N),这些景点被M(0<M≤5000)条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。频繁的改变速度使得游客们很不舒服,因此大家从一个景点前往另一个景点的时候,都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。

输入描述 Input Description

第一行包含两个正整数,N和M。
接下来的M行每行包含三个正整数:x,y和v(1≤x,y≤N,0 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。

输出描述 Output Description

如果景点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

数据范围及提示 Data Size & Hint

N(1<N≤500)

M(0<M≤5000)

Vi在int范围内

 
【题目分析】
    
    首先我们可以发现,输出impossible的情况,如果两个点的father不是同一个那么无法连通
    如果能连通的话,找到所有边中最大的和最小的,然后一边建边一边判断,一直建到两个节点能联通时,此时的maxn和minn就是最大值和最小值,然后比较与ans的大小,如果比ans小就算是比较舒适的路线,改变值
    最后一个gcd 因为要输出既约分数
 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
struct node
{
    int st,en,dis;
}a[5005];
int father[505],start,end;
int getfa(int x)
{
    if(father[x]==x)
        return x;
    else
        return father[x]=getfa(father[x]);
}
void unite(int x,int y)
{
    int xx=getfa(x);
    int yy=getfa(y);
    if(xx!=yy)
        father[yy]=xx;
}
int GCD(int x,int y)
{
    if(x%y==0)
        return y;
    else
        return GCD(y,x%y);
}
bool cmp(node x,node y)
{
    return x.dis<y.dis;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&a[i].st,&a[i].en,&a[i].dis);
    for(int i=1;i<=n;i++)
        father[i]=i;
    for(int i=1;i<=m;i++)
        unite(a[i].st,a[i].en);
    scanf("%d%d",&start,&end);
    if(getfa(start)!=getfa(end))
    {
        printf("IMPOSSIBLE");
        return 0;
    }
    sort(a+1,a+m+1,cmp);
    double ans=1000010;
    double maxn,minn;
    int max1,min1;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
            father[j]=j;
        maxn=a[i].dis;
        for(int j=i;j>=1;j--)
        {
            minn=a[j].dis;
            unite(a[j].st,a[j].en);
            if(getfa(start)==getfa(end))
            {
                if((maxn/minn)<ans)
                {
                    max1=maxn;
                    min1=minn;
                    ans=maxn/minn;
                    break;
                }
                break;
            }
        }
    }
    if(max1%min1==0)
    {
        cout<<max1/min1;
        return 0;
    }
    else
    {
        cout<<max1/GCD(max1,min1)<<"/"<<min1/GCD(max1,min1);
        return 0;
    }
}

 

posted @ 2016-08-24 11:07  [lemon]  阅读(402)  评论(0编辑  收藏  举报
……