zoukankan      html  css  js  c++  java
  • [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间能否联通,如果可以联通,则求出这条路径上最大权值与最小权值的比值。

    首先如果不考虑这个权值比值的关系,那么这道题可以直接用Kruskal来建一个生成树判断能否联通(当然也可以用别的方法来判断),那么如果有比值这个条件应该怎么判断?我们不好确定要用哪些边来连一条路径,但是显然是先将权值进行排序,然后取其中数组下标连续的一些边来连接是最优的(想一想为什么)。那么我们就可以来枚举一个边权的最小值,然后不断连边,直到S,T连通,如果可以连通了,就停止继续连边,因为再继续连边会使得最大值变大,无法使答案更优。然后这个题目就可以转化成了一个枚举最小边权的生成树,算法时间复杂度为O(m*(m+n))。然后就是一些判断输出方式的小技巧了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=500;
     4 const int M=5000;
     5 const int inf=2147483647;
     6 
     7 int s, t;
     8 int n, m;
     9 int fa[N];
    10 int mn, mx;
    11 int ans1 = inf, ans2 = 1;
    12 
    13 struct bian{
    14     int st, ed, w;
    15     bool operator < (const bian &a){
    16     return w < a.w;
    17     }
    18 }a[M];
    19 
    20 int find(int x){
    21     if(x == fa[x]) return x;
    22     return fa[x] = find(fa[x]);
    23 }
    24 
    25 int Gcd(int a,int b){
    26     return b==0?a:Gcd(b,a%b);
    27 }
    28 
    29 int main(){
    30     //freopen("data.in","r",stdin);
    31     cin >> n >> m;
    32     for(int i=1;i<=m;i++)
    33     cin >> a[i].st >> a[i].ed >> a[i].w;
    34     cin >> s >> t;
    35     sort(a+1 , a+m+1);
    36     for(int i=1;i<=m;i++){
    37         int mn = inf , mx = -inf;
    38         for(int j=1;j<=n;j++) fa[j] = j;
    39         for(int j=i;j<=m && find(s)!=find(t);j++){
    40             int r1 = find(a[j].st) , r2 = find(a[j].ed);
    41             if(r1 != r2){
    42                 fa[r1] = r2;
    43                 mn = min(mn , a[j].w);
    44                 mx = max(mx , a[j].w);
    45             }
    46         }
    47         if(find(s) == find(t) && double (ans1*1.0/ans2) > double (mx*1.0/mn))
    48         ans1 = mx , ans2 = mn;
    49     }
    50     int gcd = Gcd(ans1 , ans2);
    51     if(ans1 == inf){printf("IMPOSSIBLE
    "); return 0;}
    52     if(gcd == ans2) printf("%d
    ",ans1/ans2);
    53     else printf("%d/%d
    ",ans1/gcd,ans2/gcd);
    54     return 0;
    55 }
  • 相关阅读:
    项目开源-基于ASP.NET Core和EF Core的快速开发框架
    YoyoGo使用指南
    使用SpringSecurity Oauth2.0实现自定义鉴权中心
    Go语言系列之手把手教你撸一个ORM(一)
    记一次容器CPU高占用问题排查
    Spring Boot系列 八、集成Kafka
    Spring Boot系列:七、 实现Mybatis多数据源切换
    SpringBoot系列:六、集成Swagger文档
    MyBatis系列:二、配置文件详解
    MyBatis系列:一、入门
  • 原文地址:https://www.cnblogs.com/BCOI/p/8616608.html
Copyright © 2011-2022 走看看