【最短路/floyd模板】旅途
题目描述
您曾经带领着我,穿过我的白天的拥挤不堪的旅程,而到达了我的黄昏的孤寂之境。在通宵的寂静里,我等待着它的意义。
神即将带领一些人去他们的孤寂之境,由于这个世界的不稳定,地点之间的有向道路会不定期地毁坏,出于工作准备,神想知道在某些道路毁坏之后某两点之间的最短路。
就是给定一个有向图,现有两个操作,操作 1 是删除一条边(一条边可重复删除),操作 2是询问两个点之间的最短路。
神即将带领一些人去他们的孤寂之境,由于这个世界的不稳定,地点之间的有向道路会不定期地毁坏,出于工作准备,神想知道在某些道路毁坏之后某两点之间的最短路。
就是给定一个有向图,现有两个操作,操作 1 是删除一条边(一条边可重复删除),操作 2是询问两个点之间的最短路。
输入
第1行两个正整数n,m,分别表示图的点数和操作数。
第2行至第n+1行每行n个正整数,为图的邻接矩阵,第i行第j列的数表示点i和点j间距离,保证对角线为0。
接下来m行每行三个正整数c,x,y,c表示操作种类,为1或2,当c=1时表示删除x与y相连的边,当c=2时表示询问x到y的最短路,若不可达则输出−1。
第2行至第n+1行每行n个正整数,为图的邻接矩阵,第i行第j列的数表示点i和点j间距离,保证对角线为0。
接下来m行每行三个正整数c,x,y,c表示操作种类,为1或2,当c=1时表示删除x与y相连的边,当c=2时表示询问x到y的最短路,若不可达则输出−1。
输出
输出若干行,每个2操作对应一行,答案为询问中x到y的最短路或−1
#include<bits/stdc++.h> #define ll long long using namespace std; const int INF=1e9; int n,m; int mp[205][205]; int vis[205][205]; struct node { int f,u,v; int len; }c[100005]; int main() { scanf("%d %d",&n,&m); for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { scanf("%d",&mp[i][j]); } } for(int i=1;i<=m;++i) { scanf("%d %d %d",&c[i].f,&c[i].u,&c[i].v); if(c[i].f==1) { c[i].len=mp[c[i].u][c[i].v]; mp[c[i].u][c[i].v]=INF; vis[c[i].u][c[i].v]++; } } for(int k=1;k<=n;++k) { for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]); } } } //cout<<mp[4][1]<<endl; int ant[100005]; for(int i=m;i>=1;--i) { if(c[i].f==1) { --vis[c[i].u][c[i].v]; if(!vis[c[i].u][c[i].v]){ int cnt=min(mp[c[i].u][c[i].v],c[i].len); for(int a=1;a<=n;a++) { for(int b=1;b<=n;b++) { mp[a][b]=min(mp[a][b],mp[a][c[i].u]+cnt+mp[c[i].v][b]); } } } } else { if(mp[c[i].u][c[i].v]<INF) { ant[i]=mp[c[i].u][c[i].v]; } else { ant[i]=-1; } } } for(int i=1;i<=m;++i) { if(c[i].f==2){ printf("%d\n",ant[i]); } } return 0; }