Graph HDU - 4034(floyd)

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

题意:
给你n个点最短路,求至少多少个边
思路:
首先最短路已经确定了
那么出现d(i, j) > d(i, k) + d(k, j)一定是错误的。

n个点的图,最多有n*(n-1)条边。一条一条边的审查就好了。
要是d(i, j) = d(i, k) + d(k, j) ,那么 i 到 j 这条边没有用。

因为最短路是确定的,最基础的边删除不了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

int d[105][105];

int main()
{
    int T;scanf("%d",&T);
    int kase = 0;
    while(T--)
    {
        int n;scanf("%d",&n);
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= n;j++)
            {
                scanf("%d",&d[i][j]);
            }
        }
        
        int flag = 0;
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= n;j++)
            {
                for(int k = 1;k <= n;k++)
                {
                    if(i != j && j != k && i != k)
                        if(d[i][j] > d[i][k] + d[k][j])
                        {
                            flag = 1;
                            break;
                        }
                }
            }
        }
        
        if(flag)
        {
            printf("Case %d: impossible\n",++kase);
            continue;
        }
        
        int ans = 0;
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= n;j++)
            {
                if(i != j)
                {
                    flag = 1;
                    for(int k = 1;k <= n;k++)
                    {
                        if(i != k && j != k)
                        {
                            if(d[i][j] == d[i][k] + d[k][j])
                            {
                                flag = 0;
                                break;
                            }
                        }
                    }
                    if(flag)
                    {
                        ans++;
                    }
                }
            }
        }
        printf("Case %d: %d\n",++kase,ans);
    }
    return 0;
}

发布了594 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/103965714