题目链接:传送门
题意描述:
有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;
}