Atcoder 083 Restoring Road Network(类弗洛伊德)

题目链接

题意

一共有N个城市,通过N-1条边连接。
现在给出一个N x N的矩阵,表示从i->j的最短路径,求能否根据这个N x N的矩阵求出最短路,如果最短路出错,输出-1

解决

       k
       /\
      /  \
   i /____\ j
  1. 因为N只有300级别,所以可以n^3算法
  2. 设三个点 i , j ,k
  3. 如果存在i->k + k->j的最短路径和< i->j的最短距离,那么这个矩阵是错误的。
  4. 如果存在i->k + k->j的最短路径和= i->j的最短距离,那么i->j的这条边是不需要存在的(走同样的路程,能通过更多的点(k点),所以选择i->k->j而不是i->j)
#include<bits/stdc++.h>
using namespace std;
int maps[305][305];
bool flag[305][305];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
            scanf("%d",&maps[i][j]);
        }
    }

    bool ok = true;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                if(i==j) continue;
                if(i==k) continue;
                if(j==k) continue;
                if(maps[i][k]+maps[k][j] < maps[i][j]) ok = false;  //存在比“最短路”更短的路,错误
                if(maps[i][k]+maps[k][j] == maps[i][j]) flag[i][j] = flag[j][i] = 1;
                                                //从i到j的边是不需要存在的
            }
        }
    }

    if(!ok){
        puts("-1");
        return 0;
    }

    long long ans = 0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j) continue;
            if(flag[i][j]) continue;    //不需要存在的路
            ans += maps[i][j];
        }
    }
    printf("%lld\n",ans/2);             //i->j j->i算了两遍
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章