• bzoj1050 [HAOI2006]旅行comf


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

    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

    【数据范围】
    1< N < = 500
    1 < = x, y < = N,0 < v < 30000,x ≠ y
    0 < M < =5000

    题意是求从S到T的路径的最大边比最小边的最小比值

    把边按权值排序,那么要取的边肯定是这些边中的一段区间

    那么答案就是区间的最右边权值除以最左边权值的最小值

    很容易想到枚举区间的左端点,然后用并查集找第一条使ST联通的边

    至于分数输出那种花哨的东西自己yy一下就好了

    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    struct node{
        int from,to;
        int path;
    }data[5001];
    int fa[501];
     
    bool cmp(const node &a,const node &b)
    {return a.path < b.path;}
     
    int find(int x)
    {return fa[x] == x ? x : fa[x] = find(fa[x]);}
     
    int gcd(int a,int b)
    {
        if (b == 0) return a;
        return gcd(b,a%b);
    }
     
    int min(int a,int b)
    {return a<b?a:b;}
         
    void quit()
    {
        printf("IMPOSSIBLE");
        exit(0);
    }
    int main()
    {
        int n,m,s,t;
        int savel = 0,saver = 0;
        bool noans = 1;
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
          scanf("%d%d%d",&data[i].from,&data[i].to,&data[i].path);
        sort(data+1,data+m+1,cmp);
        scanf("%d%d",&s,&t);
        int start = 1;
        while (start <= m)
          {
            int l = 0,r = 0,j = 0;
            for (int i=1;i<=n;i++) fa[i] = i;
            for (j=start;j<=m;j++)
              {
                int x = find(data[j].from);
                int y = find(data[j].to);
                fa[x] = y;
                if (find(s) == find(t))
                  {
                    r = data[j].path;
                    break;
                  }
              }
            if (r == 0) 
              {
                if (noans) quit();
                break;
              }
            for (int i=1;i<=n;i++) fa[i] = i;
            for (;j>=1;j--)
              {
                int x = find(data[j].from);
                int y = find(data[j].to);
                fa[x] = y;
                if (find(s) == find(t))
                  {
                    l = data[j].path;
                    break;
                  }
              }
             
            start = j+1;
            if (l == 0)
              {
                if (noans) quit();
                break;
              }
            int d = gcd(r,l);
            r /= d; 
            l /= d;
            if (saver == 0 && savel == 0 )
            {
                noans = 0;
                saver = r;
                savel = l;
            }else
            if (saver*l > savel*r)
              {
                noans = 0;
                savel = l;saver = r;
              }
          }
       
        if (noans) quit(); 
        else if (savel == 1) printf("%d",saver);
        else printf("%d/%d",saver,savel);
    } 


    ——by zhber,转载请注明来源
  • 相关阅读:
    【Oracle/MyBatis】Oracle分页语句在MyBatis的Mapper.xml中的实际运用
    ZT:ResultSet的getDate()、getTime()和getTimestamp()比较
    【Oracle】使用sqlldr命令行从csv文件获得数据导入Oracle数据库某表中,如果有数据包括逗号,该怎么办?
    如何在 Linux 中以脚本模式运行 Top
    CentOS 8 安装 Caddy Web服务器
    CentOS下Jenkins安装&&Jenkins端口修改不生效踩坑记录
    Windows 服务器禁用 SSL 2 和 SSL 3 协议 itprobie
    C# Task 使用 WhenAll 和 WaitAll 需要注意的坑
    C# 使用 protobuf 手动生成
    Go gin 接入 prometheus
  • 原文地址:https://www.cnblogs.com/zhber/p/4035939.html
Copyright © 2020-2023  润新知