[CF1321D]Navigation System
【原題】
The map of Bertown can be represented as a set ofnnintersections, numbered from11tonnand connected bymmone-way roads. It is possible to move along the roads from any intersection to any other intersection. The length of some path from one intersection to another is the number of roads that one has to traverse along the path. The shortest path from one intersection
Polycarp lives near the intersectionssand works in a building near the intersectiontt. Every day he gets fromsstottby car. Today he has chosen the following path to his workplace:p1p1,p2
Polycarp's car has a complex navigation system installed in it. Let's describe how it works. When Polycarp starts his journey at the intersectionss, the system chooses some shortest path fromsstottand shows it to Polycarp. Let's denote the next intersection in the chosen path asvv. If Polycarp chooses to drive along the road fromsstovv, then the navigator shows him the same shortest path (obviously, starting fromvvas soon as he arrives at this intersection). However, if Polycarp chooses to drive to another intersectionwwinstead, the navigatorrebuildsthe path: as soon as Polycarp arrives atww, the navigation system chooses some shortest path fromwwtottand shows it to Polycarp. The same process continues until Polycarp arrives attt: if Polycarp moves along the road recommended by the system, it maintains the shortest path it has already built; but if Polycarp chooses some other path, the systemrebuildsthe path by the same rules.
Here is an example. Suppose the map of Bertown looks as follows, and Polycarp drives along the path[1,2,3,4][1,2,3,4](s=1s=1,t=4t=4):
Check the picture by the linkhttp://tk.codeforces.com/a.png
- When Polycarp starts at11, the system chooses some shortest path from11to44. There is only one such path, it is[1,5,4][1,5,4];
- Polycarp chooses to drive to22, which is not along the path chosen by the system. When Polycarp arrives at22, the navigatorrebuildsthe path by choosing some shortest path from22to44, for example,[2,6,4][2,6,4](note that it could choose[2,3,4][2,3,4]);
- Polycarp chooses to drive to33, which is not along the path chosen by the system. When Polycarp arrives at33, the navigatorrebuildsthe path by choosing the only shortest path from33to44, which is[3,4][3,4];
- Polycarp arrives at44along the road chosen by the navigator, so the system does not have to rebuild anything.
Overall, we get22rebuilds in this scenario. Note that if the system chose[2,3,4][2,3,4]instead of[2,6,4][2,6,4]during the second step, there would be only11rebuild (since Polycarp goes along the path, so the system maintains the path[3,4][3,4]during the third step).
The example shows us that the number of rebuilds can differ even if the map of Bertown and the path chosen by Polycarp stays the same. Given this information (the map and Polycarp's path), can you determine the minimum and the maximum number of rebuilds that could have happened during the journey?
InputThe first line contains two integersnnandmm(2≤n≤m≤2⋅1052≤n≤m≤2⋅105) — the number of intersections and one-way roads in Bertown, respectively.
Thenmmlines follow, each describing a road. Each line contains two integersuuandvv(1≤u,v≤n1≤u,v≤n,u≠vu≠v) denoting a road from intersectionuuto intersectionvv. All roads in Bertown are pairwise distinct, which means that each ordered pair(u,v)(u,v)appears at most once in thesemmlines (but if there is a road(u,v)(u,v), the road(v,u)(v,u)can also appear).
The following line contains one integerkk(2≤k≤n2≤k≤n) — the number of intersections in Polycarp's path from home to his workplace.
The last line containskkintegersp1p1,p2p2, ...,pkpk(1≤pi≤n1≤pi≤n, all these integers are pairwise distinct) — the intersections along Polycarp's path in the order he arrived at them.p1p1is the intersection where Polycarp lives (s=p1s=p1), andpkpkis the intersection where Polycarp's workplace is situated (t=pkt=pk). It is guaranteed that for everyi∈[1,k−1]i∈[1,k−1]the road frompipitopi+1pi+1exists, so the path goes along the roads of Bertown.
OutputPrint two integers: the minimum and the maximum number ofrebuildsthat could have happened during the journey.
Examples input Copy6 9 1 5 5 4 1 2 2 3 3 4 4 1 2 6 6 4 4 2 4 1 2 3 4output Copy
1 2input Copy
7 7 1 2 2 3 3 4 4 5 5 6 6 7 7 1 7 1 2 3 4 5 6 7output Copy
0 0input Copy
8 13 8 7 8 6 7 5 7 4 6 5 6 4 5 3 5 2 4 3 4 2 3 1 2 1 1 8 5 8 7 5 2 1output Copy
0 3
【思路】
最短路,pre[i]記錄每個結點的前驅結點。如果下一結點是當前結點的前驅結點並且當前結點的前驅結點個數>1,最大重驅次數++。如果下一結點是當前結點的前驅結點並且當前結點的前驅結點個數 == 1, 那麼無法進行重驅。如果下一結點不是當前結點的前驅結點,最大、最小重驅次數++。
(之前用num陣列存當前點最短路個數,爆LL了)
1 #include <algorithm> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <list> 6 #include <map> 7 #include <iostream> 8 #include <queue> 9 #include <set> 10 #include <stack> 11 #include <string> 12 #include <vector> 13 #include <iomanip> 14 #define LL long long 15 #define inf 0x3f3f3f3f 16 #define INF 0x3f3f3f3f3f3f 17 #define PI 3.1415926535898 18 #define F first 19 #define S second 20 #define lson rt << 1 21 #define rson rt << 1 | 1 22 using namespace std; 23 24 const int maxn = 2e5 + 7; 25 const int maxm = 4e5 + 7; 26 int n, m; 27 string s; 28 vector<int> v, pre[maxn]; 29 map < pair<int, int>, int > mp; 30 struct pp 31 { 32 int v, w, next; 33 }edge[maxn]; 34 int head[maxn], dis[maxn], vis[maxn], path[maxn], cnt = 0; 35 struct node 36 { 37 int u, dis; 38 bool operator < (const node& a) const 39 { 40 return a.dis < dis; 41 } 42 }; 43 void add(int t1, int t2, int t3) 44 { 45 edge[++cnt].v = t2; 46 edge[cnt].w = t3; 47 edge[cnt].next = head[t1]; 48 head[t1] = cnt; 49 } 50 void dijkstra(int b) 51 { 52 priority_queue<node> que; 53 int i; 54 memset(dis, inf, sizeof(dis)); 55 memset(vis, 0, sizeof(vis)); 56 dis[b] = 0; 57 node temp; 58 temp.u = b; temp.dis = 0; 59 que.push(temp); 60 while (!que.empty()) 61 { 62 int u = que.top().u; 63 que.pop(); 64 if (vis[u]) continue; 65 vis[u] = 1; 66 for (i = head[u]; i; i = edge[i].next) 67 { 68 int v = edge[i].v; 69 if (vis[v]) continue; 70 if (dis[v] == dis[u] + edge[i].w) 71 { 72 pre[v].push_back(u); 73 } 74 if (dis[v] > dis[u] + edge[i].w) 75 { 76 dis[v] = dis[u] + edge[i].w; 77 temp.u = v; temp.dis = dis[v]; 78 que.push(temp); 79 pre[v].clear(); 80 pre[v].push_back(u); 81 } 82 } 83 } 84 } 85 86 int main() 87 { 88 ios::sync_with_stdio(false); 89 cin.tie(0); 90 cin >> n >> m; 91 int ta, tb; 92 for (int i = 1; i <= m; i++) 93 { 94 cin >> ta >> tb; 95 add(tb, ta, 1); 96 mp[{ta, tb}] = cnt; 97 } 98 int k; 99 cin >> k; 100 for (int i = 1; i <= k; i++) 101 { 102 cin >> path[i]; 103 } 104 dijkstra(path[k]); 105 int mn = 0, mx = 0; 106 for (int i = 1; i <= k - 1; i++) 107 { 108 if (pre[path[i]].size() > 1 && dis[path[i]] - dis[path[i + 1]] == edge[mp[{ path[i], path[i + 1] }]].w) 109 { 110 mx++; 111 } 112 else if(dis[path[i]] - dis[path[i + 1]] != edge[mp[{ path[i], path[i + 1] }]].w) 113 { 114 mn++; 115 mx++; 116 } 117 } 118 cout << mn << " " << mx << endl; 119 120 }