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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章