zoukankan      html  css  js  c++  java
  • [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; }
  • 相关阅读:
    数据库自动备份
    VC查找文件特定位置的记录方法
    MFC利用ADO连接ACCESS数据库及其操作数据库的方法
    VC利用ODBC连接MySql数据库的方法及其操作数据的方法
    uwsgi和nginx的故事
    A JavaScript Image Gallery
    The DOM in JavaScript
    A brief look at the Objects in JavaScript
    3 ways of including JavaScript in HTML
    #3 working with data stored in files && securing your application (PART II)
  • 原文地址:https://www.cnblogs.com/hhh1109/p/8438369.html
Copyright © 2011-2022 走看看