1 条题解

  • -2
    @ 2020-01-23 16:05:38

    如果一条边ij的边权可以增大 说明一定有一个中间点k构成的折线长度\(ik+kj<=ij\)
    那么ij的最大长度可以为INF 也就是说每条边的长度要么不变 要么为INF
    因此得到
    算法一:枚举删去一条边ij 然后跑floyd 如果没有一个点对的距离改变 则这条边可以为INF 复杂度n^5
    算法二:枚举边ij 跑floyd判断那些点在ij之间的最短路上 只要存在中间点在最短路上 那么ij之间的连线就可以为INF

    /*
    
    */
    #define method_1
    #ifdef method_1
    /*
    
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iomanip>
    #include<ctime>
    #include<string>
    #include<bitset>
    #define D(x) cout<<#x<<" = "<<x<<"  "
    #define E cout<<endl
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>pii;
    const int maxn=100+5;
    const int INF=0x3f3f3f3f;
    int T;
    int n;
    int d[maxn][maxn];
    void solve(){
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(i==j||i==k||j==k) continue;
                    if(d[i][j]==d[i][k]+d[k][j]) d[i][j]=INF;
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(d[i][j]==INF) cout<<"infty"<<" ";
                else cout<<d[i][j]<<" ";
            } 
            cout<<endl;
        }
    }
    int main() {
    //  ios::sync_with_stdio(false);
        //freopen("无向图最短路径.in","r",stdin);
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&d[i][j]);
            solve();    
        }
        return 0;
    }
    #endif
    #ifdef method_2
    /*
    
    */
    
    #endif
    #ifdef method_3
    /*
    
    */
    
    #endif
    
    
  • 1

信息

ID
1122
难度
2
分类
(无)
标签
(无)
递交数
30
已通过
21
通过率
70%
上传者