zoukankan      html  css  js  c++  java
  • [Vijos 2024]无向图最短路径

    Description

    无向图最短路径问题,是图论中最经典也是最基础的问题之一。本题我们考虑一个有 $n$ 个结点的无向图 $G$。
    $G$ 是简单完全图,也就是说 $G$ 中没有自环,也没有重边,但任意两个不同的结点之间都有一条带权的双向边。
    每一条边的边权是非负实数,但我们并不知道每一条边的具体边权。
    好消息是我们知道 $G$ 中任意两点最短路径的长度$d(i,j)$。且保证至少有一种边权的分配方案满足得到的带权图中$i$与$j$的最短路长度恰好是$d(i,j)$。
    下面是留给你的任务:对于任意一对点$(i,j)$,希望你能找出来所有合法的边权分配方案中$i$和$j$之间边权的最大值。

    Input

    本题中,每一组数据都有多次询问,每一次询问分别给出了一个无向图$G$。
    输入的第一行是一个整数 $t$,表示总共的询问个数。之后依次给出每一次询问。
    对于每一次询问来说,第一行给出了 $G$ 中结点总数 $n$。之后$n$行每行有$n$个整数,给出了一个$n imes n$的矩阵 $d$,其中第$i$行第$j$列的整数对应 $d(i,j)$表示$i$到$j$的最短路径长度。
    因为图$G$是简单无向图,对角线元素$d(i,i)$总是$0$,且矩形是对称的(也就是说$d(i,j)=d(j,i)$)。

    Output

    对于每一次询问,若给定的图$G$有$n$个结点,则输出$n$行,每行有$n$个整数,描述了一个矩阵 $a$。矩阵的第$i$行第$j$列表示连接$i$和$j$的边的最大可能边权。如果$(i,j)$的边权可以任意大,则输出字符串infty表示无限。
    矩阵的对角线没有实质性意义,请全输出$0$。因为$G$是无向图,所以输出的矩阵$a$应该也是对称的(即$a(i,j)=a(j,i)$)。
    不难发现,因为给定的矩阵 $d$ 中每一个数字都是整数,所以最大可能边权总会是整数。

    Sample Input

    2
    3
    0 2 8
    2 0 10
    8 10 0
    3
    0 1 1
    1 0 1
    1 1 0

    Sample Output

    0 2 8
    2 0 infty
    8 infty 0
    0 1 1
    1 0 1
    1 1 0

    HINT

    对于 $20\%$ 的数据,有 $n = 3$。
    对于 $50\%$ 的数据,有 $1le nle 10$。
    对于 $100\%$ 的数据,有 $1le nle 100$,且所有询问中$n$的和不超过 $800$,对于所有的$d$满足$1le dle 256$。
    每一组数据的时限为 $0.5$ 秒。

    题解

    这道题应该不难想吧...

    我们把最短路边作为边权,还用类似$floyd$的过程,若存在$f[i][j] == f[i][k]+f[k][j]$,显然我$i<->j$这条边的边权可以为任意$>=f[i][j]$的值,显然就是$infty$;

    若不存在,即只有这条边满足条件,边权不能比最短路大也不能小,那么就是原值。

     1 //It is made by Awson on 2017.10.13
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <cmath>
     7 #include <stack>
     8 #include <queue>
     9 #include <vector>
    10 #include <string>
    11 #include <cstdio>
    12 #include <cstdlib>
    13 #include <cstring>
    14 #include <iostream>
    15 #include <algorithm>
    16 #define LL long long
    17 #define Min(a, b) ((a) < (b) ? (a) : (b))
    18 #define Max(a, b) ((a) > (b) ? (a) : (b))
    19 #define sqr(x) ((x)*(x))
    20 using namespace std;
    21 const int N = 100;
    22 
    23 int n, f[N+5][N+5];
    24 bool judge[N+5][N+5];
    25 
    26 void work() {
    27     scanf("%d", &n);
    28     memset(judge, 0, sizeof(judge));
    29     for (int i = 1; i <= n; i++)
    30         for (int j = 1; j <= n; j++)
    31             scanf("%d", &f[i][j]);
    32     for (int k = 1; k <= n; k++)
    33         for (int i = 1; i <= n; i++) if (i != k)
    34             for (int j = 1; j <= n; j++) if (j != k && i != j)
    35                 if (f[i][j] == f[i][k]+f[k][j]) judge[i][j] = 1;
    36     for (int i = 1; i <= n; i++) {
    37         for (int j = 1; j <= n; j++)
    38             if (judge[i][j]) printf("infty ");
    39             else printf("%d ", f[i][j]);
    40         printf("
    ");
    41     }
    42 }
    43 int main() {
    44     int t; scanf("%d", &t);
    45     while (t--) work();
    46     return 0;
    47 }
  • 相关阅读:
    洛谷 1443——马的遍历(广度优先搜索)
    jzoj C组 2017.1.21
    jzoj C组 2017.1.20 比赛
    jzoj C组 2017.1.19 比赛
    jzoj C组 2017.1.18 比赛
    jzoj C组 2017.1.17 比赛
    jzoj C组 2017.1.16 比赛
    jzoj C组 2017.1.15比赛
    [LCA][数学]JZOJ 4794 富爷说是一棵树
    [CDQ分治][带权并查集]JZOJ 4769
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7663455.html
Copyright © 2011-2022 走看看