• 最舒适的路线(并查集)


    最舒适的路线

    时间限制:5000 ms  |  内存限制:65535 KB
     
    描述

    异形卵潜伏在某区域的一个神经网络中。其网络共有N个神经元(编号为1,2,3,…,N),这些神经元由M条通道连接着。两个神经元之间可能有多条通道。异形卵可以在这些通道上来回游动,但在神经网络中任一条通道的游动速度必须是一定的。当然异形卵不希望从一条通道游动到另一条通道速度变化太大,否则它会很不舒服。

    现在异形卵聚居在神经元S点,想游动到神经元T点。它希望选择一条游动过程中通道最大速度与最小速度比尽可能小的路线,也就是所谓最舒适的路线。

     
    输入
    第一行: K 表示有多少组测试数据。 
    接下来对每组测试数据:
    第1行: N M
    第2~M+1行: Xi Yi Vi (i=1,…..,M)
    表示神经元Xi 到神经元Yi之间通道的速度必须是Vi
    最后一行: S T ( S  T )

    【约束条件】
    2≤K≤5 1<N≤500 0<M≤5000 1≤ Xi, Yi , S , T ≤N 0< Vi <30000,
    Vi是整数。数据之间有一个空格。
    输出
    对于每组测试数据,输出一行:如果神经元S到神经元T没有路线,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
    样例输入
    2
    3 2
    1 2 2
    2 3 4
    1 3
    3 3
    1 2 10
    1 2 5
    2 3 8
    1 3
    
    样例输出
    2
    5/4
    
    来源
    第六届河南省程序设计大赛
    思路:枚举速度最大的那条边,一条条插入比它速度小的边,直到两地连通——这里可以使用并查集,逐个比较比值,取最小的就行了。
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 #define INF 20000000
     7 
     8 struct point{
     9     int x, y, v;
    10 };
    11 
    12 point node[5005];
    13 int fa[505];
    14 
    15 bool cmp(point a, point b)
    16 {
    17     return a.v < b.v;//边从小到大
    18 }
    19 int find(int n)
    20 {
    21     return n == fa[n] ? n : fa[n] = find(fa[n]);
    22 }
    23 int gcd(int a, int b)
    24 {
    25     return b ? gcd(b, a%b) : a;
    26 }
    27 int main()
    28 {
    29     int i, j, t, e;
    30     int start, end, row, edge, maxv, minv;
    31     double radio;
    32     cin>>t;
    33     while(t--)
    34     {
    35         cin>>row>>edge;
    36         for(i = 1; i <= edge; i++){
    37             cin>>node[i].x>>node[i].y>>node[i].v;
    38         }
    39         cin>>start>>end;
    40         sort(node + 1, node+edge + 1, cmp);
    41         radio = INF;
    42         for(e = edge; e > 0; e--){//从最大的边开始,将比它小的边加入
    43             for(i =1; i <= row; i++)fa[i] = i;
    44             for(i = e; i > 0; i--){
    45                 int a = find(node[i].x);
    46                 int b = find(node[i].y);
    47                 if(a == b)continue;
    48                 else fa[a] = b;
    49                 if(find(start) == find(end))break;//起点和终点在都一个集合里
    50             }
    51             if(i == 0)break;//如果把边都加进去完了,说明起点和终点不连通
    52             if(node[e].v/(node[i].v*1.0) < radio){
    53                 radio = node[e].v / (node[i].v * 1.0);
    54                 maxv = node[e].v;
    55                 minv = node[i].v;
    56             }
    57         }
    58         int g = gcd(maxv, minv);
    59         if(radio == INF)printf("IMPOSSIBLE
    ");
    60         else if(maxv % minv == 0)printf("%d
    ", maxv / minv);
    61         else printf("%d/%d
    ", maxv/g, minv/g);
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    java中数组的相关知识
    如何搭建Java开发环境(包括下载、安装和配置JDK)和Eclipse的安装
    java 8种基本数据类型的默认值及所占字节数
    C语言编写的简单的电话本管理系统
    C语言题库的上机题
    Spring Boot使用AJAX从数据库读取数据异步刷新前端表格
    JS,jQuery获取select标签中选中值的方法
    jQuery效果与扩展:左右滑动
    使用EasyUI创建分页对比效果
    一些关于链表操作的代码
  • 原文地址:https://www.cnblogs.com/qiu520/p/3657073.html
Copyright © 2020-2023  润新知