[Codeforces 864F]Cities Excursions
Description
There are n cities in Berland. Some pairs of them are connected with m directed roads. One can use only these roads to move from one city to another. There are no roads that connect a city to itself. For each pair of cities (x, y) there is at most one road from x to y.
A path from city s to city t is a sequence of cities p1, p2, ... , pk, where p1 = s, pk = t, and there is a road from city pi to city pi + 1 for each ifrom 1 to k - 1. The path can pass multiple times through each city except t. It can't pass through t more than once.
A path p from s to t is ideal if it is the lexicographically minimal such path. In other words, p is ideal path from s to t if for any other path qfrom s to t pi < qi, where i is the minimum integer such that pi ≠ qi.
There is a tourist agency in the country that offers q unusual excursions: the j-th excursion starts at city sj and ends in city tj.
For each pair sj, tj help the agency to study the ideal path from sj to tj. Note that it is possible that there is no ideal path from sj to tj. This is possible due to two reasons:
- there is no path from sj to tj;
- there are paths from sj to tj, but for every such path p there is another path q from sj to tj, such that pi > qi, where i is the minimum integer for which pi ≠ qi.
The agency would like to know for the ideal path from sj to tj the kj-th city in that path (on the way from sj to tj).
For each triple sj, tj, kj (1 ≤ j ≤ q) find if there is an ideal path from sj to tj and print the kj-th city in that path, if there is any.
Input
The first line contains three integers n, m and q (2 ≤ n ≤ 3000,0 ≤ m ≤ 3000, 1 ≤ q ≤ 4·105) — the number of cities, the number of roads and the number of excursions.
Each of the next m lines contains two integers xi and yi (1 ≤ xi, yi ≤ n, xi ≠ yi), denoting that the i-th road goes from city xi to city yi. All roads are one-directional. There can't be more than one road in each direction between two cities.
Each of the next q lines contains three integers sj, tj and kj (1 ≤ sj, tj ≤ n, sj ≠ tj, 1 ≤ kj ≤ 3000).
Output
In the j-th line print the city that is the kj-th in the ideal path from sj to tj. If there is no ideal path from sj to tj, or the integer kj is greater than the length of this path, print the string '-1' (without quotes) in the j-th line.
Sample Input
7 7 5
1 2
2 3
1 3
3 4
4 5
5 3
4 6
1 4 2
2 6 1
1 7 3
1 3 2
1 3 5
Sample Output
2
-1
-1
2
-1
题解
最后一题竟然耗了(沉迷B站无法自拔)三个小时。
给出一个有向图。对于每个询问,你需要去找到从$s_i$到$t_i$字典序最小的路径上第$k_i$个点。
首先按终点$t_i$分组,找到所有和$t_i$连通的节点。可以通过将所有的边反向并且从$t_i$开始$dfs$来实现。
现在,我们考虑询问$(s_i,t_i)$。对于这组询问,你需要去找到从$s_i$到$t_i$字典序最小的路径。如果节点$t_i$与$s_i$不连通,那么答案就是'$-1$'。值得注意的是,如果字典序最小的路径成为一个环,那么答案也是'$-1$'。
因此,我们建一个新图包括原图的所有的反向边。枚举所有的终点$t$,从$t$遍历整个图,取前驱节点最优路径,发现所有与$t$相连的点构成了一棵外向树,那么这些在树上的点与根节点之间的路径就是题目要求的字典序最小的路径。(注意是在“树”上,若形成环显然不行)
接着我们可以用倍增来找从$s$开始的第$k$个节点。
1 //It is made by Awson on 2017.9.29 2 #include <set> 3 #include <map> 4 #include <cmath> 5 #include <ctime> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <cstdio> 10 #include <string> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 #define LL long long 16 #define Max(a, b) ((a) > (b) ? (a) : (b)) 17 #define Min(a, b) ((a) < (b) ? (a) : (b)) 18 #define sqr(x) ((x)*(x)) 19 #define lowbit(x) ((x)&(-(x))) 20 using namespace std; 21 const int N = 3000; 22 const int Q = 4e5; 23 void read(int &x) { 24 char ch; bool flag = 0; 25 for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar()); 26 for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar()); 27 x *= 1-2*flag; 28 } 29 30 int n, m, q, u, v, k; 31 int lim, f[N+5][15]; 32 int ans[Q+5]; 33 struct tt { 34 int to, next, k, id; 35 }edge[N+5], query[Q+5]; 36 int path_e[N+5], top_e; 37 int path_q[N+5], top_q; 38 39 void add_e(int u, int v) { 40 edge[++top_e].to = v; 41 edge[top_e].next = path_e[u]; 42 path_e[u] = top_e; 43 } 44 void add_q(int u, int v, int k, int id) { 45 query[++top_q].to = v; 46 query[top_q].next = path_q[u]; 47 query[top_q].k = k; 48 query[top_q].id = id; 49 path_q[u] = top_q; 50 } 51 void dfs(int u, int fa) { 52 for (int i = path_e[u]; i; i = edge[i].next) 53 if (edge[i].to != fa && (f[edge[i].to][0] == 0 || f[edge[i].to][0] > u)) 54 f[edge[i].to][0] = u, dfs(edge[i].to, fa); 55 } 56 void work() { 57 read(n), read(m), read(q); 58 lim = log(n)/log(2)+1; 59 for (int i = 1; i <= m; i++) { 60 read(u), read(v); 61 add_e(v, u); 62 } 63 for (int i = 1; i <= q; i++) { 64 read(u), read(v), read(k); 65 add_q(v, u, k, i); 66 } 67 for (int i = 1; i <= n; i++) { 68 memset(f, 0, sizeof(f)); 69 dfs(i, i); 70 for (int t = 1; t <= lim; t++) 71 for (int j = 1; j <= n; j++) 72 f[j][t] = f[f[j][t-1]][t-1]; 73 for (int j = path_q[i]; j; j = query[j].next) { 74 int u = query[j].to, id = query[j].id, k = query[j].k-1; 75 if (f[u][lim] || (!f[u][0])) { 76 ans[id] = -1; 77 continue; 78 } 79 for (int t = 0; k; k >>= 1, t++) 80 if (k&1) u = f[u][t]; 81 ans[id] = u ? u : -1; 82 } 83 } 84 for (int i = 1; i <= q; i++) 85 printf("%d\n", ans[i]); 86 } 87 int main() { 88 work(); 89 return 0; 90 }