Roads in Berland

题目链接:传送门

题意描述:

       有n座城市在Berland,然后给你一个n*n的矩阵,表示第i座城市和第j座城市的最短路径。现在,Berland政府计划修建k条新道路。对于每条规划中的道路,我们知道它的长度以及它将连接的城市。为了控制新道路建设的正确性,在另一条道路开通后,Berland政府希望检查所有城市之间最短距离的总和。

题目分析:

       这道题一看就是求最短路径的问题,而且是用邻接矩阵法来表示路径的长度的,那么,很显然是Floyd算法,但如果用完整的Floyd算法时间复杂度为300^4,明显会超时。所以,要用到小小的优化。因为每次修改的路径只是两个点,那么,其他路径如果变短的话肯定会经过这两个点,所以我们Floyd的时候只遍历这两个点作为中间变量的就行,少了一次循环,时间复杂度为300^3.还要注意的是最后总路径长度会爆int的,要用long long存。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, k, m[304][304];
ll ans[304];
int main(){
    cin >> n;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j) scanf("%d", &m[i][j]);
    cin >> k;
    int u, v, val;
    for(int d=1;d<=k;++d){
        scanf("%d %d %d", &u, &v, &val);
        if(val < m[u][v]){
            m[u][v] = m[v][u] = val;
            for(int i=1;i<=n;++i){
                for(int j=1;j<=n;++j) m[i][j] = m[j][i] = min(m[i][j], m[i][u]+m[u][j]);
            }
            for(int i=1;i<=n;++i){
                for(int j=1;j<=n;++j) m[i][j] = m[j][i] = min(m[i][j], m[i][v]+m[v][j]);
            }
        }
        ll sum = 0;
        for(int i=1;i<=n;++i){
            for(int j=i+1;j<=n;++j){
                sum += m[i][j];
            }
        }
        ans[d] = sum;
    }
    for(int i=1;i<k;++i) printf("%lld ", ans[i]);
    printf("%lld\n", ans[k]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41100093/article/details/87876065