zoukankan      html  css  js  c++  java
  • Graph(Floyd)

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

    Graph

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
    Total Submission(s): 2058    Accepted Submission(s): 1030


    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 ,如果在求得过程中发现有dist[i][j]>dist[i][k]+dist[k][j]的情况就说明所给的不是最短的路图,及impossible

    而在求解的过程中,当dist[i][j]==dist[i][k]+dist[k][j]的时候说明从i 到j 的长度,可以通过k点到达,故可以将直接相连的i,j去掉,及标记dist[i][j] = INF;

    注意两点: 1,可以先将impossible的情况单独先算出来,以防后面对dist[i][j]  = INF ;

    2, 当i==j||j==k||j==k 的时候要continue掉,因为这个为0的点会更新其他所有的点

    下面是代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 #define N 103
     6 #define INF 0x1fffffff
     7 int mp[N][N];
     8 int dist[N][N];
     9 int main()
    10 {
    11     int i , j , k ;
    12     int n;
    13     int t ;
    14     cin>>t;
    15     int c = 0;
    16     while(t--)
    17     {
    18         c++;
    19         scanf("%d",&n);
    20         for( i = 0 ; i < n ;i++)
    21         {
    22             for(  j = 0 ; j < n ;j++)
    23             {
    24                 scanf("%d",&mp[i][j]);
    25                 dist[i][j] = mp[i][j];
    26             }
    27         }
    28         bool flag = true;
    29         for(k = 0 ;flag && k < n ; k++)
    30         {
    31             for(i = 0 ;flag && i < n ; i++)
    32             {
    33                 for( j = 0 ; flag&& j < n ;j++)
    34                 {
    35                     if(dist[i][j]>dist[i][k]+dist[k][j])
    36                         flag = false;
    37                 }
    38             }
    39         }
    40         int cnt = 0;
    41         if(flag)
    42         {
    43             for( k = 0 ; k < n ;k++)
    44             {
    45                 for(i = 0 ; i < n ;i++)
    46                 {
    47                     for(j = 0 ;j < n ;j++)
    48                     {
    49                         if(i==j||j==k||k==i) continue;
    50                         if(dist[i][j]==dist[i][k]+dist[k][j])
    51                             {
    52                                 dist[i][j] = INF;
    53                                 //printf("%d %d %d
    ", k ,i , j);
    54                                 cnt++;
    55                             }
    56                     }
    57                 }
    58             }
    59         }
    60         if(flag) printf("Case %d: %d
    ",c,n*(n-1)-cnt);
    61         else printf("Case %d: impossible
    ",c);
    62 
    63     }
    64     return 0 ;
    65 }
  • 相关阅读:
    面试题63 二叉搜索树的第k个结点
    面试题62 序列化二叉树
    面试题61 把二叉树打印成多行
    面试题60 按之字形顺序打印二叉树
    centos下Nginx代理访问web服务
    回文数
    两数之和--哈希表unordered_map
    删除链表的倒数第N个节点---链表的应用
    基础篇,排序(冒泡排序,快速排序)
    linuxC网络聊天室简单代码,CSDN博客迁移
  • 原文地址:https://www.cnblogs.com/shanyr/p/4678652.html
Copyright © 2011-2022 走看看