zoukankan      html  css  js  c++  java
  • [BZOJ1050][HAOI2006]旅行

    题目描述

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

    输入输出格式

    输入格式:

    第一行包含两个正整数,N和M。

    接下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。

    最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。

    输出格式:

    如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。

    输入输出样例

    输入样例#1: 
    4 2
    1 2 1
    3 4 2
    1 4
    输出样例#1: 
    IMPOSSIBLE
    输入样例#2: 
    3 3
    1 2 10
    1 2 5
    2 3 8
    1 3
    输出样例#2: 
    5/4
    输入样例#3: 
    3 2
    1 2 2
    2 3 4
    1 3
    输出样例#3: 
    2

    说明

    【数据范围】

    1<N≤500

    1≤x,y≤N,0<v<30000,x≠y

    0<M≤5000


    一看这种题满脑子都是并查集,貌似好像貌似...被洗脑了?

    我们先按边权从小到大排序,然后枚举最小的路径是哪个,之后合并集合,一旦发现s, t在一个集合,就把当前路径的边权除以枚举最小路径的边权来更新答案。

    于是乎...做完了。


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    inline int read(){
        int res=0;char ch=getchar();
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
        return res; 
    }
    
    int n, m, s, t;
    struct edge{
        int x, y, val;
    }ed[10005];
    inline bool cmp(edge a, edge b){return a.val < b.val;} 
    int fa[505];
    int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);}
    int ans1, ans2, res1, res2;
    int gcd(int x, int y){return y==0?x:gcd(y, x%y);}
    
    int main()
    {
        n = read(), m = read();
        for (int i = 1 ; i <= m ; i ++) 
        {
            int x = read(), y = read(), z = read();
            ed[i] = (edge){x, y, z};
        }
        s = read(), t = read();
        sort(ed + 1, ed + 1 + m, cmp);
        ans1 = 1e9; ans2 = 1;
        for (int i = 1 ; i <= m ; i ++)
        {
            for (int j = 1 ; j <= n ; j ++) fa[j] = j;        
            for (int j = i ; j <= m ; j ++)
            {
                int x = ed[j].x, y = ed[j].y;
                int fx = Find(x), fy = Find(y);
                if (fx == fy) continue;
                fa[fx] = fy;    
                int fs = Find(s), ft = Find(t);
                if (fs == ft) 
                {
                    res1 = ed[j].val, res2 = ed[i].val;
                    break;
                }            
            }
            if ((double)((double)ans1 / (double)ans2) >= (double)((double)res1 / (double)res2)) ans1 = res1, ans2 = res2;
        }
        if (ans1 == 1e9 and ans2 == 1) return puts("IMPOSSIBLE"), 0;
        if (ans1 % ans2 == 0) return printf("%d
    ", ans1/ans2), 0;
        int g = gcd(ans1, ans2);
        return printf("%d/%d", ans1/g, ans2/g), 0;
    }
  • 相关阅读:
    BZOJ2563 阿狸和桃子的游戏
    BZOJ2460 Beijing2011元素(线性基+贪心)
    BZOJ2458 Beijing2011最小三角形(分治)
    BZOJ2442 Usaco2011 Open修剪草坪(动态规划+单调队列)
    Luogu2257 YY的GCD/BZOJ2818 Gcd加强版(莫比乌斯反演+线性筛)
    BZOJ2428 HAOI2006均分数据(模拟退火)
    BZOJ2440 中山市选2011完全平方数(容斥原理+莫比乌斯函数)
    洛谷 P1783 海滩防御 解题报告
    洛谷 P2431 正妹吃月饼 解题报告
    洛谷 P2751 [USACO4.2]工序安排Job Processing 解题报告
  • 原文地址:https://www.cnblogs.com/BriMon/p/9373208.html
Copyright © 2011-2022 走看看