题目大意:有一个由n个点组成的无向图,给你一个邻接表,a_i,j代表从i到j的最短距离,接下来会有k次操作,每次操作会新建一条从x到y的路,求每次操作完,更新后的邻接表的每个元素和的一半。
解题思路:每次操作更新x与y间的距离,首先要判断a_x,y是否需要更新,然后利用floyd算法更新其他的最短距离,但如果每次都直接更新,那复杂度是n^3*k会超时,所以考虑优化。又每次更新只更新一条边,所以用floyd时只需要更新恰好经过x或者经过y的路径,这样的话复杂度就是n^2*k。最后注意结果是把所有邻接表的元素求和,所以会爆int,需要用long long。
AC代码:
#include <iostream> #include <algorithm> using namespace std; typedef long long LL; int n; LL mat[310][310] = {0}; void floyd(int t) { for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++) { mat[i][j] = min(mat[i][j],mat[i][t]+mat[t][j]); mat[j][i] = mat[i][j]; } } int main() { cin >> n; for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++) cin >> mat[i][j]; int k = 0; cin >> k; for(int i = 0;i<k;i++) { int x,y; LL d; cin >> x >> y >> d; mat[x][y] = min(d,mat[x][y]); mat[y][x] = mat[x][y]; floyd(x); floyd(y); LL res = 0; for(int i = 1;i<=n;i++) for(int j = i+1;j<=n;j++) res+=mat[i][j]; if(i == 0)cout << res; else cout << " " << res; } cout << endl; return 0; }