• [HAOI2006]旅行(并查集)


    寒假填坑五十道省选题——第五道

    [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

      第一眼看这个题目发现有些熟悉,才发现是教练在我刚接触信息三四个月时就考过的qwq,当时怎么可能会做嘛orz。

      不过那个时候就听懂了题解,这道题根本不用去跑什么最短路什么的,直接一个克鲁斯卡尔+队列就好了,把边从小到大排,然后暴力每一条边为出发点,不断向右边找,直到s==t,这样就能求出比值最小的边了。

      

    //It's made by Epiphyllum 2018/2/10
    #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #define ll long long using namespace std; int s,t,n,m,fa[50001],ans1,ans2; struct node{ int vi,x,y; }ch[500001]; int read() { int x=0,w=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*w; } bool cmp(node a,node b) { return a.vi<b.vi; } int find(int x) { if (fa[x]==x) return x; return fa[x]=find(fa[x]); } int gcd(int x,int y) { if (y>x) return gcd(y,x); if (!y) return x; return gcd(y,x%y); } int main() { n=read();m=read(); for(int i=1;i<=m;i++) { ch[i].x=read();ch[i].y=read();ch[i].vi=read(); } s=read();t=read(); sort(ch+1,ch+m+1,cmp); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++)fa[j]=j; int j; for(j=i;j<=m;j++) { int fx,fy; fx=find(ch[j].x);fy=find(ch[j].y); if(fx==fy)continue; fa[fx]=fy; if(find(s)==find(t))break; } if ((i==1)&&(find(s)!=find(t))) { printf("IMPOSSIBLE "); return 0; } if(find(s)!=find(t))break; if(ans1*ch[i].vi>=ans2*ch[j].vi) ans1=ch[j].vi,ans2=ch[i].vi; } int x=gcd(ans1,ans2); if (x==ans2) printf("%d ",ans1/ans2); else printf("%d/%d ",ans1/x,ans2/x); return 0; }
  • 相关阅读:
    ASP.NET MVC路由规则
    VS2013 修改TFS的本地映射路径
    新安装的VS的一些设置
    ASP.NET MVC验证标注的扩展-checkbox必选
    进入做Mvc项目的时候 返现某个文件夹下面css js png等静态文件都访问不了
    Mac入门 (二) 使用VMware Fusion虚拟机
    Mac入门(一)基本用法
    软件测试面试 (二) 如何测试网页的登录页面
    软件测试面试 (一) 如何测试一个杯子
    Python自动化测试 (二) ConfigParser模块读写配置文件
  • 原文地址:https://www.cnblogs.com/hhh1109/p/8438369.html
Copyright © 2020-2023  润新知