码迷,mamicode.com
首页 > 其他好文 > 详细

[Vijos 2024]无向图最短路径

时间:2017-10-13 23:43:54      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:ctime   vijos   意义   图论   mat   多次   ace   消息   一个   

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\times 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\%$ 的数据,有 $1\le n\le 10$。
对于 $100\%$ 的数据,有 $1\le n\le 100$,且所有询问中$n$的和不超过 $800$,对于所有的$d$满足$1\le d\le 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("\n");
41     }
42 }
43 int main() {
44     int t; scanf("%d", &t);
45     while (t--) work();
46     return 0;
47 }

 

[Vijos 2024]无向图最短路径

标签:ctime   vijos   意义   图论   mat   多次   ace   消息   一个   

原文地址:http://www.cnblogs.com/NaVi-Awson/p/7663455.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!