zoukankan      html  css  js  c++  java
  • WHU 1542 Countries (floyd)

    题意:

      在小明出生的星球X上有n国家。

      一些国家通过结盟而拥有良好的双边关系,因此他们的公民得益于这些政策,使得所有这些国家之间的旅行变得免费。

      但是,不同联盟之间的旅行就不是这么容易了。如果可能,它必须花一些钱。

      请帮小明计算出国家之间的最小花费。

      输入:

        输入包含多组样例。

        每组样例的第一行有两个整数 n 和 m 。(1<=n<=10^5, 1<=m<=10^5)

        接下来的m行,每行有x, y, c。 其中 c 表示 x, y之间的花费。如果c为0,则表示x和y属于同一个联盟。(1<=x, y<=n, 0<=c<=10^9)

        你可以假设两个国家之间没有多于一条路。

        然后下一行是一个整数q,代表有多少个询问。(1<=q<=200)

        接下来有q行,每行包括x, y。(1<=x, y<=n)

        保证不会超过两百个联盟。

        当输入n=0时,结束。

      输出:

        对于每组输入,每个询问输出一行。如果不可能,输出"-1"。

    思路:

      对于同一个联盟的国家,我们可以把他们看成一个国家,因为他们一定是连起来的。 然后跑floyd。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 typedef long long ll;
     9 
    10 const int MAXN = (int) 1e5+7;
    11 const int MAXC = 205;
    12 
    13 struct Edge{
    14     int x, y;
    15     ll c;
    16 }a[MAXN];
    17 
    18 int p[MAXN];
    19 int f[MAXN];
    20 ll d[MAXC][MAXC];
    21 int n, m, q;
    22 int cnt;
    23 
    24 int Find(int x) {
    25     int res = x;
    26     int t;
    27 
    28     while (f[res]!=res) res = f[res];
    29     while (x!=res) {
    30         t = x;
    31         x = f[x];
    32         f[t] = res;
    33     }
    34     return res;
    35 }
    36 
    37 void Union(int x, int y) {
    38     f[Find(x)] = Find(y);
    39 }
    40 
    41 void floyd() {
    42     for (int k = 0; k < cnt; k++)
    43         for (int i = 0; i < cnt; i++)
    44             for (int j = 0; j < cnt; j++)
    45                 if (-1!=d[i][k] && -1!=d[k][j]) {
    46                     if (-1==d[i][j]) {
    47                         d[i][j] = d[i][k]+d[k][j];
    48                     } else
    49                         d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
    50                 }
    51 }
    52 
    53 int main() {
    54     #ifdef Phantom01
    55         freopen("WHU1542.txt", "r", stdin);
    56     #endif // Phantom01
    57 
    58     while (scanf("%d", &n)!=EOF) {
    59         if (0==n) break;
    60         scanf("%d", &m);
    61         cnt = 0;
    62         for (int i = 1; i <= n; i++)
    63             f[i] = i;
    64         for (int i = 0; i < m; i++) {
    65             scanf("%d%d%lld", &a[i].x, &a[i].y, &a[i].c);
    66             if (0 == a[i].c) Union(a[i].x, a[i].y);
    67         }
    68         for (int i = 1; i <= n; i++) {
    69             if (i==f[i]) //如果是根,
    70                 p[i] = cnt++;
    71         }
    72         for (int i = 0; i < cnt; i++) {
    73             for (int j = 0; j < cnt; j++)
    74                 d[i][j] = -1;
    75             d[i][i] = 0;
    76         }
    77         int x, y;
    78         for (int i = 0; i < m; i++) {
    79             x = p[Find(a[i].x)];
    80             y = p[Find(a[i].y)];
    81             d[x][y] = -1==d[x][y] ? a[i].c : min(d[x][y], a[i].c);
    82             d[y][x] = -1==d[y][x] ? a[i].c : min(d[y][x], a[i].c);
    83         }
    84         floyd();
    85         scanf("%d", &q);
    86         for (int i = 0; i < q; i++) {
    87             scanf("%d%d", &x, &y);
    88             printf("%lld
    ", d[p[Find(x)]][p[Find(y)]]);
    89         }
    90     }
    91 
    92     return 0;
    93 }
    View Code

      

  • 相关阅读:
    SQL server 数据库基础语句
    数据库学习的第一天
    C# 函数
    C# for循环的嵌套 作用域
    C# for循环语句
    Docker的基本使用
    django连接postgresql
    docker的安装
    Postgresql的使用
    Celery的介绍
  • 原文地址:https://www.cnblogs.com/Phantom01/p/3643955.html
Copyright © 2011-2022 走看看