首页 > 代码库 > codevs 1001 舒适的路线

codevs 1001 舒适的路线

题目描述 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范围内

 
分析:
简单的并查集,加上一点小贪心。类似最小生成树。
首先将路线按照速度从小到大排序
枚举每个最大速度 然后再找小于最大速度的路线
利用并查集 将边联通起来 构成个生成树 看s,t是否可以联通 找到直接比较更新max_ans与min_ans即可。
 
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
const int inf=9999999;
struct node{
    int s;
    int f;
    int w;
}a[5010];
int fx[501];
int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
void init()
{
    for(int i=1;i<=n;++i)fx[i]=i;
}
bool cmp(const node &a,const node &b)
{
    return a.w<b.w;
}
int find(int n)
{
    if(fx[n]==n)return n;
    else return fx[n]=find(fx[n]);
}
bool mer(int s,int f)
{
    int a=find(s),b=find(f);
    if(a!=b)
    {
        fx[b]=a;
        return 1;
    }
    else return 0;
}
int main()
{
    
    int max_ans=inf,min_ans=1;
    int s,t;
    cin>>n>>m;
    for(int i=1;i<=m;++i)cin>>a[i].s>>a[i].f>>a[i].w;
    cin>>s>>t;
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=m;++i)
    {
        init();
        for(int j=i;j>=1;--j)
        {
            mer(a[j].s,a[j].f);
            if(find(s)==find(t))
            {
                if((double)max_ans/min_ans>(double)a[i].w/a[j].w)
                {
                    max_ans=a[i].w;
                    min_ans=a[j].w;
                    break;
                }
            }
        }
    }
    if(max_ans==inf&&min_ans==1)
    {
        cout<<"IMPOSSIBLE";
        return 0;
    }
    //cout<<max_ans<<" "<<max_min;
    if(max_ans%min_ans==0)
    {
        cout<<max_ans/min_ans;
    }
    else
    {
        int t;
        t=gcd(max_ans,min_ans);
        max_ans/=t;
        min_ans/=t;
        cout<<max_ans<<"/"<<min_ans;
    }
    return 0;
    
    
}

 

 

codevs 1001 舒适的路线