zoukankan      html  css  js  c++  java
  • HDU 4034 Graph(Floyd变形——逆向判断)

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4034

    Problem 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
    题意描述:
    输入使用Floyd算法跑出来的最短路径的邻接矩阵
    判断是否有这样的图存在,存在输出图中至少需要几条边,不存在输出impossible
    解题思路:
    首先分为存在和不存在两种情况
    不存在意味该图中存在至少一条边的最短路径是错误的,例如图中存1--->2为3,2--->3为4,而图中存储的是2--->3为8,很明显可以通过2这个点将1--->3这条边松弛为7,那么这条最短路径是错误的,近而判断不存在这样的图;
    再说存在这样的图的情况,如果存在这样的图,根据题中所说为单向道路,n个顶点最多有n*(n-1)条边,如果某一条边可以消去,那么必定可以找到与直接路径相等的间接路径,例如图中存1--->2为3,2--->3为4,而图中存储的是1--->3为7,很明显可以将1--->3这条边消去。
    另外,每次判断,需要用book数组来记录那一条边已经消去过了,否则可能重复消去。
    代码实现:
     1 #include<stdio.h>
     2 #include<string.h>
     3 int n,map[110][110],book[110][110];
     4 int floyd();
     5 int main()
     6 {
     7     int T,t=0,i,j,flag;
     8     scanf("%d",&T);
     9     while(T--)
    10     {
    11         scanf("%d",&n);    
    12         for(i=1;i<=n;i++)
    13             for(j=1;j<=n;j++)
    14                 scanf("%d",&map[i][j]);
    15         flag=floyd();
    16         if(flag)
    17         printf("Case %d: %d
    ",++t,flag);
    18         else
    19         printf("Case %d: impossible
    ",++t);
    20     }
    21     return 0;
    22 }
    23 int floyd()
    24 {
    25     int i,j,k,ans;
    26     memset(book,0,sizeof(book));
    27     ans=n*(n-1);
    28     for(k=1;k<=n;k++)
    29     for(i=1;i<=n;i++)
    30         for(j=1;j<=n;j++)
    31             if(i != j&&i != k&&j != k)
    32             {
    33                 if(!book[i][j] && map[i][j] == map[i][k]+map[k][j])
    34                 {
    35                     ans--;
    36                     book[i][j]=1;
    37                 }
    38                 else if(map[i][j] > map[i][k]+map[k][j])
    39                 return 0;
    40             }
    41     return ans;
    42 }
     
     
  • 相关阅读:
    大爽Python入门教程 45 实践使用
    大爽pyqt5笔记&教程 四 布局 Layout 对其
    大爽Python入门教程 47 答案
    大爽Python入门教程 46 习题
    大爽Python入门教程 43 函数传参 形参、实参 default、*args、**kwargs
    大爽Python入门教程 41 初识函数Function
    大爽Python入门教程 56 实践练习 功能添加
    检测密码是否能过强度检测(正则表达式检测)
    常用加密算法汇总一下
    [转]技术人员,你拿什么拯救你的生活温水煮青蛙
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/7509395.html
Copyright © 2011-2022 走看看