【最短路】旅程

题目描述

您曾经带领着我,穿过我的白天的拥挤不堪的旅程,而到达了我的黄昏的孤寂之境。在通宵的寂静里,我等待着它的意义。

神即将带领一些人去他们的孤寂之境,由于这个世界的不稳定,地点之间的有向道路会不定期地毁坏,出于工作准备,神想知道在某些道路毁坏之后某两点之间的最短路。
就是给定一个有向图,现有两个操作,操作 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操作对应一行,答案为询问中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 }
View Code

 

posted @ 2019-01-25 15:19  听风不成泣  阅读(207)  评论(0编辑  收藏  举报