zoukankan      html  css  js  c++  java
  • Codevs 1001 舒适的路线 2006年 NOIP全国联赛提高组

    1001 舒适的路线 2006年
    时间限制: 2 s
    空间限制: 128000 KB
    题目等级 : 钻石 Diamond
    题目描述 Description
    Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。
    Z小镇附近共有N(2<=N≤500)个景点(编号为1,2,3,…,N),这些景点被M(1<=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(2<=N≤500)
    M(1<=M≤5000)
    Vi在int范围内
    分类标签 Tags
    并查集 树结构 2006年

    /*
    好题好题好题.
    考场上绝对想不出来(看到图论题不会忘这方面想orz.)
    一开始想二分答案但并不具单调性.
    (二分答案其实就是优化的枚举吧)
    这题其实和求瓶颈MST的方法有些类似
    并查集加边就可以了.
    排序后枚举一条最大的边倒着往前找加边
    直到u和v在一个集合里更新答案.
    图的连通性问题完全可以用并查集维护orz.
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MAXN 5001
    using namespace std;
    int father[MAXN],n,m,tot,u,v,ans1,ans2;
    double ans=1e9,max1,min1;
    struct data{int x,y,z;}s[MAXN*2];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    bool cmp(const data &x,const data &y)
    {
        return x.z<y.z;
    }
    int find(int x)
    {
        return x!=father[x]?father[x]=find(father[x]):x;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=m;i++)
          s[i].x=read(),s[i].y=read(),s[i].z=read();
        sort(s+1,s+m+1,cmp);
        u=read(),v=read();
        for(int k=1;k<=m;k++)
        {
            max1=s[k].z;
            for(int i=1;i<=n;i++) father[i]=i;
            for(int i=k;i>=1;i--)
            {
                int l1=find(s[i].x),l2=find(s[i].y);
                father[l2]=l1;
                if(find(u)==find(v))
                {
                    min1=s[i].z;
                    if(max1/min1<ans)
                    {
                        ans=max1/min1;
                        ans1=max1,ans2=min1;
                    }
                    break;
                }
            }
        }
        if(ans==1e9)
        {
            printf("IMPOSSIBLE");
            return 0;
        }
        int x=__gcd(ans1,ans2);
        ans1/=x,ans2/=x;
        if(ans2==1) printf("%d",ans1);
        else printf("%d/%d",ans1,ans2);
        return 0;
    }
  • 相关阅读:
    tableView的高度问题
    信任机型
    cell 内部 设置width 总不对
    图文混排
    UICollectionview实现自定义cell的移动删除
    ios 各种技术
    打包ane之后在FB上生成ipa的阶段错误
    自动布局出代码植入 的图像化实例
    MapReduce编程实例
    二叉树的遍历(递归遍历、非递归遍历、层序遍历)
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070763.html
Copyright © 2011-2022 走看看