zoukankan      html  css  js  c++  java
  • hdu 4034 【floyed变形】

    Graph

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


    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
     
     



    题意:读入矩阵,矩阵中存储的是i到j的最短路径,问,原图中的最小路径总数为多少?不存在原图,按题目输出

    思路:floyed的变形。既然矩阵中存储的已经是最短路径,那么此矩阵中每条路径都必然满足最优值,比如第三个样例,直接从1到3的最短路径是4,而通过1到2(最短路径是1)再从2到3(最短路径是2)总的最短路径是3,比直接从1到3更短,不满足题目所说的条件,输出“impossible",所以,此样例给我们提供了一种思路:比较直接到达的最短路径w[i][j]和通过一个中转点k的路径w[i][k]+w[k][j]的值的大小。如果二者相等,说明直接到达的这条边取消也不影响原图,如果前者大于后者,说明不满足条件。记得定义一个标记数组,对已经访问过的点进行标记。

    #include<stdio.h>
    #include<string.h>
    #define N 110
    int w[N][N],vis[N][N],n,sum,flag,ans;
    int Count()
    {
        int i,j,k;
        for(i = 1; i <= n; i ++)
            for(j = 1; j <= n; j ++)
                for(k = 1; k <= n; k ++)
                {
                    if(i!=j&&j!=k&&k!=i)//自身到自身的情况不用考虑 
                    {
                        if(w[i][j] == w[i][k] + w[k][j]&&!vis[i][j])
                        {
                            vis[i][j] = 1;//如果满足最短路径的条件,标记为访问过 
                            ans ++;//可取消的边数增加 
                        }
                        if(w[i][j] > w[i][k] + w[k][j])//如果不满足最短路径的条件,结束函数 
                            return 0;
                    }    
                }
        return 1;
    }
    int main()
    {
        int t,i,j;
        scanf("%d",&t);
        int t2 = 0;
        while(t--)
        {
            scanf("%d",&n);
            memset(vis,0,sizeof(vis));//标记数组 
            for(i = 1; i <= n; i ++)
                for(j = 1; j <= n; j ++)
                {
                    scanf("%d",&w[i][j]);
                    if(i == j)//自身到自身的下标标记为已经访问过 
                        vis[i][j] = 1;
                }
            sum = n*n-n;//总的边数 
            ans = 0;
            printf("Case %d: ",++t2);
            if(Count())
                printf("%d
    ",sum-ans);//总边数减去可以取消的边数就是原图最小的边数 
            else
                printf("impossible
    ");
        }
        return 0;
    }

     

  • 相关阅读:
    github release 文件下载贼慢,干脆失败的解决方法
    windows 下sublime text 3 配置python 环境详解
    Ubuntu下安装并使用sublime text 3(建议:先安装Package controls 后在看本教程,否则可能会安装不了)
    将博客搬至CSDN
    signalr core客户端通过ssl连接服务的方式
    解决html导出pdf中文乱码问题的正确姿势
    记一次asp.net core 在iis上运行抛出502.5错误
    Elasticsearch 集群搭建
    bower私服部署
    体验Code::Blocks下的Windows GUI编程(32 bit and 64 bit)
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7510804.html
Copyright © 2011-2022 走看看