【最短路】旅程
题目描述
您曾经带领着我,穿过我的白天的拥挤不堪的旅程,而到达了我的黄昏的孤寂之境。在通宵的寂静里,我等待着它的意义。
神即将带领一些人去他们的孤寂之境,由于这个世界的不稳定,地点之间的有向道路会不定期地毁坏,出于工作准备,神想知道在某些道路毁坏之后某两点之间的最短路。
就是给定一个有向图,现有两个操作,操作 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
样例输入
5 6
0 6 6 10 10
2 0 7 8 6
10 5 0 10 3
9 5 8 0 7
4 9 8 3 0
1 2 3
1 4 1
2 1 3
1 4 2
1 1 2
2 4 1
样例输出
6
11
样例输出
6
11
1 #include <iostream> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int INF = 123456789; 5 const int maxn = 2e5+50; 6 typedef long long ll; 7 ll edge[250][250]; 8 int n,m; 9 ll fr[maxn],to[maxn],op[maxn],ans[maxn],len[maxn]; 10 map<pair<int,int>,int > mp; 11 void floyd() 12 { 13 for(register int k=1;k<=n;k++) 14 { 15 for(register int i=1;i<=n;i++) 16 { 17 for(register int j=1;j<=n;j++) 18 { 19 edge[i][j]=min(edge[i][j],edge[i][k]+edge[k][j]); 20 } 21 } 22 } 23 } 24 int main() 25 { 26 scanf("%d%d",&n,&m); 27 for(register int i=1;i<=n;i++) 28 { 29 for(register int j=1;j<=n;j++) 30 { 31 scanf("%lld",&edge[i][j]); 32 } 33 } 34 for(register int i=1;i<=m;i++) 35 { 36 scanf("%lld%lld%lld",&op[i],&fr[i],&to[i]); 37 if(op[i]==1) 38 { 39 len[i]=edge[fr[i]][to[i]]; 40 edge[fr[i]][to[i]]=INF; 41 mp[make_pair(fr[i],to[i])]++; 42 } 43 } 44 floyd(); 45 int tot=0; 46 for(register int k=m;k>=1;k--) 47 { 48 if(op[k]==1) 49 { 50 mp[make_pair(fr[k],to[k])]--; 51 if(!mp[make_pair(fr[k],to[k])]) 52 { 53 for(register int i=1;i<=n;i++) 54 { 55 for(register int j=1;j<=n;j++) 56 { 57 edge[i][j]=min(edge[i][j],edge[i][fr[k]]+edge[to[k]][j]+len[k]); 58 } 59 } 60 } 61 } 62 else 63 { 64 ans[++tot]=edge[fr[k]][to[k]]; 65 } 66 } 67 for(register int i=tot;i>=1;i--) 68 { 69 if(ans[i]>=INF) 70 printf("-1\n"); 71 else 72 printf("%lld\n",ans[i]); 73 } 74 //cout << "Hello world!" << endl; 75 return 0; 76 }