C: Restoring Road Network(Floyd拓展应用)

问题 C: Restoring Road Network
时间限制: 1 Sec 内存限制: 128 MB
提交: 894 解决: 183
[提交] [状态] [讨论版] [命题人:admin]
题目描述

In Takahashi Kingdom, which once existed, there are N cities, and some pairs of cities are connected bidirectionally by roads. The following are known about the road network:
People traveled between cities only through roads. It was possible to reach any city from any other city, via intermediate cities if necessary.
Different roads may have had different lengths, but all the lengths were positive integers.
Snuke the archeologist found a table with N rows and N columns, A, in the ruin of Takahashi Kingdom. He thought that it represented the shortest distances between the cities along the roads in the kingdom.
Determine whether there exists a road network such that for each u and v, the integer Au,v at the u-th row and v-th column of A is equal to the length of the shortest path from City u to City v. If such a network exist, find the shortest possible total length of the roads.

Constraints
1≤N≤300
If i≠j, 1≤Ai,j=Aj,i≤109.
Ai,i=0

输入

Input is given from Standard Input in the following format:
N
A1,1 A1,2 … A1,N
A2,1 A2,2 … A2,N

AN,1 AN,2 … AN,N

输出

If there exists no network that satisfies the condition, print -1. If it exists, print the shortest possible total length of the roads.

样例输入

3
0 1 3
1 0 2
3 2 0

样例输出

3

提示

The network below satisfies the condition:
City 1 and City 2 is connected by a road of length 1.
City 2 and City 3 is connected by a road of length 2.
City 3 and City 1 is not connected by a road.
题意:有一个N*N的地图,二位坐标,每两个点之间都有一条路,权值(长度)任意。一个点到另外一个点的时候中间可以经过其他点,假设对每一对(u,v)他们之间的最小权值都等于输入的原数据,那就计算求出图中所有路的总和。否则不满足条件的就输出-1.
思路:一开始理解错了题意,由于英语不好,错误的理解成如果每两点之间的最短路等于输入的原值就求出该图的最短路,导致增加了好多罚时—_—!!
这道题正确的思路是如果每两点之间的最短路等于输入的原值的话就求出途中所有路的总和。在这里求每两点之间的最短路时可以用Floyd算法,如果满足要求,接下来就是如何不重复的计算路径之和。由Floyd算法中借助中间点来更新最短路的思路,我们可以借助中间点来找上筛选出两点之间有中间点的路径,这样在计算的只要把两点之间没有中间点的路径记入总和即可。
例题给的测试数据经分析可知0到1的长度为1,1到2 的长度为2,0到2的长度为3,即点0到2的路经过点1。这时候我们只需要将01,12之间的路径加和即可。即路径总和是每两点所确定的直线的长度加起来的,中间有多余点的路径都不符合加入的条件。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int father[350];
LL Map[350][350],Map1[350][350];

int main()
{
    int n; cin>>n;
    for(int i=0;i<n;i++)
        father[i]=i;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>Map[i][j];
            Map1[i][j]=Map[i][j];
        }
    }
    for(int k=0;k<n;k++)//更新每两点之间的最短路
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
                Map1[i][j]=min((Map1[i][k]+Map1[k][j]),Map[i][j]);
        }
    }
    int flag=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {//判断是否与原值相等
            if(Map[i][j]!=Map1[i][j])
            {
                flag=1;
                break;
            }
        }
        if(flag==1)break;
    }
    if(flag!=1)
    {
        int cnt=0;LL sum=0;
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                cnt=1;
                for(int k=0;k<n;k++)
                {
                    if((i!=k&&j!=k)&&Map[i][j]==Map[i][k]+Map[k][j])
                        cnt=0;
                }
                if(cnt==1) sum+=Map[i][j];//删去重复的路
            }
        }
        cout<<sum<<endl;
    }
    else
    cout<<"-1"<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a17865569022/article/details/81318297