hdu 4034 Graph(floyd)

来源:互联网 发布:我的世界pe矿物透视js 编辑:程序博客网 时间:2024/05/08 12:16

hdu 4034 Graph

Description
Everyone knows how to calculate the shortest path in a directed graph. In fact, the opposite problem is also easy. Given the length of shortest path between each pair of vertexes, can you find the original graph?

Input
The first line is the test case number T (T ≤ 100).
First line of each case is an integer N (1 ≤ N ≤ 100), the number of vertexes.
Following N lines each contains N integers. All these integers are less than 1000000.
The jth integer of ith line is the shortest path from vertex i to j.
The ith element of ith line is always 0. Other elements are all positive.

Output
For each case, you should output “Case k: ” first, where k indicates the case number and counts from one. Then one integer, the minimum possible edge number in original graph. Output “impossible” if such graph doesn’t exist.

Sample Input
3
3
0 1 1
1 0 1
1 1 0
3
0 1 3
4 0 2
7 3 0
3
0 1 4
1 0 2
4 2 0

Sample Output
Case 1: 6
Case 2: 4
Case 3: impossible

题目大意:给出一张图,表示的是点与点之间的最短路,问原图最少有几条边。不存在这种情况就输出-1。

解题思路:一开始没想到可以用floyd。先用floyd对原图求一次最短路,不过条件要改成G[i][j]>=G[i][k]+G[k][j],记录下可优化的最短路。然后,优化过后的图和原图作比较,若一条最短路被优化过,并且,优化过后那两点之间的最短路不变,那么cnt++。但是,如果,优化过后的最短路,小于原先的最短路,那这张图就是不存在的。最后比较完,得到cnt,用n * (n - 1)算出最多的边数,然后减去cnt,得到的答案,就是该最短路图所对应的原图的最小边数。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>using namespace std;const int N = 105;typedef long long ll;int n;int G1[N][N], G2[N][N];int vis[N][N];void floyd() {    for (int k = 0; k < n; k++) {        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                if (j == k || i == k) continue;                 if (G1[i][j] >= G1[i][k] + G1[k][j]) {                    G1[i][j] = G1[i][k] + G1[k][j];                    vis[i][j] = 1;                }            }           }       }}int main() {    int T, Case = 1;    scanf("%d", &T);    while (T--) {        printf("Case %d: ", Case++);        memset(vis, 0, sizeof(vis));        memset(G1, 0, sizeof(G1));        memset(G2, 0, sizeof(G2));        scanf("%d", &n);        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                scanf("%d", &G1[i][j]);                     G2[i][j] = G1[i][j];            }           }           floyd();        int cnt = 0, flag = 1;        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                if (vis[i][j] && G2[i][j] == G1[i][j]) {                    cnt++;                  }                if (G2[i][j] > G1[i][j]) flag = 0;            }           }        int ans = n * (n - 1) - cnt;        if (ans < n - 1 || !flag) {            printf("impossible\n");         } else printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击