voidbfs(int root){ memset(depth, 0x3f, sizeof depth); int hh = 0, tt = 0; depth[0] = 0; depth[root] = 1; q[0] = root; while (hh <= tt){ int t = q[hh++]; for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if (depth[j] > depth[t] + 1) { depth[j] = depth[t] + 1; q[++tt] = j; fa[j] = t; } } } }
intlca(int a, int b){ if (depth[a] < depth[b]) swap(a, b); while (depth[a] != depth[b]){ a = fa[a]; } if (a == b) return a; while (fa[a] != fa[b]) { a = fa[a]; b = fa[b]; } return fa[a]; } signedmain() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int root; cin >> n >> m >> root; memset(h, -1, sizeof h); for (int i = 1; i <= n - 1; i++) { int a, b; cin >> a >> b; add(a, b); add(b, a); }
bfs(root);
while(m--) { int a, b; cin >> a >> b; int p = lca(a, b); cout << p << '\n'; } return0; }
voidbfs(int root){ memset(depth, 0x3f, sizeof depth); int hh = 0, tt = 0; depth[0] = 0; depth[root] = 1; q[0] = root; while (hh <= tt){ int t = q[hh++]; for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if (depth[j] > depth[t] + 1) { depth[j] = depth[t] + 1; q[++tt] = j; fa[j][0] = t; for (int k = 1; k <= 21; k++) { fa[j][k] = fa[fa[j][k - 1]][k - 1]; } } } } }
intlca(int a, int b){ if (depth[a] < depth[b]) swap(a, b); for (int k = 21; k >= 0; k--) { if (depth[fa[a][k]] >= depth[b]) { a = fa[a][k]; } } if (a == b) return a; for (int k = 21; k >= 0; k--) { if (fa[a][k] != fa[b][k]) { a = fa[a][k]; b = fa[b][k]; } } return fa[a][0]; } signedmain() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int root; cin >> n >> m >> root; memset(h, -1, sizeof h); for (int i = 1; i <= n - 1; i++) { int a, b; cin >> a >> b; add(a, b); add(b, a); }
bfs(root);
while(m--) { int a, b; cin >> a >> b; int p = lca(a, b); cout << p << '\n'; } return0; }
voidbfs(int root){ memset(depth, 0x3f, sizeof depth); int hh = 0, tt = 0; depth[0] = 0; depth[root] = 1; q[0] = root; while (hh <= tt){ int t = q[hh++]; for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if (depth[j] > depth[t] + 1) { depth[j] = depth[t] + 1; q[++tt] = j; fa[j] = t; } } } }
intlca(int a, int b){ if (depth[a] < depth[b]) swap(a, b); while (depth[a] != depth[b]){ a = fa[a]; } if (a == b) return a; while (fa[a] != fa[b]) { a = fa[a]; b = fa[b]; } return fa[a]; } signedmain() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int root; cin >> n >> m >> root; memset(h, -1, sizeof h); for (int i = 1; i <= n - 1; i++) { int a, b; cin >> a >> b; add(a, b); add(b, a); }
bfs(root);
while(m--) { int a, b; cin >> a >> b; int p = lca(a, b); cout << p << '\n'; } return0; }
voidbfs(int root){ memset(depth, 0x3f, sizeof depth); int hh = 0, tt = 0; depth[0] = 0; depth[root] = 1; q[0] = root; while (hh <= tt){ int t = q[hh++]; for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if (depth[j] > depth[t] + 1) { depth[j] = depth[t] + 1; q[++tt] = j; fa[j][0] = t; for (int k = 1; k <= 21; k++) { fa[j][k] = fa[fa[j][k - 1]][k - 1]; } } } } }
intlca(int a, int b){ if (depth[a] < depth[b]) swap(a, b); for (int k = 21; k >= 0; k--) { if (depth[fa[a][k]] >= depth[b]) { a = fa[a][k]; } } if (a == b) return a; for (int k = 21; k >= 0; k--) { if (fa[a][k] != fa[b][k]) { a = fa[a][k]; b = fa[b][k]; } } return fa[a][0]; } signedmain() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int root; cin >> n >> m >> root; memset(h, -1, sizeof h); for (int i = 1; i <= n - 1; i++) { int a, b; cin >> a >> b; add(a, b); add(b, a); }
bfs(root);
while(m--) { int a, b; cin >> a >> b; int p = lca(a, b); cout << p << '\n'; } return0; }
Groundhog was especially careful after the outbreak,so he put on his mask in the 1st bedroom early,and then walked on the way to the nth dormitory to play with Orange. There are n dormitories in ZLZX, which are connected by n−1 corridors. Each dormitory can be reached to each other.The length of each corridor is 1.The walking speed of Groundhog is 1 m/s.
At that moment the bad news came: After Groundhog set out for t{t}t seconds,Orange took his temperature, and it turned out to be 41℃ !!! In addition to grief and indignation, Orange decided to run to Groundhog, to tell him the news at the speed of 2 m/s.
Groundhog had to run, of course, but he was running too slow at 1 m/s . As he ran, he had an idea: if he ran with the best strategy, how soon would Orange catch up with him? Define that every second Groundhog moves and then Orange moves again. Groundhog can choose to stay put. Groundhog would have solved that, of course, but he is running away now, so he give it to you, the smartest one.
输入描述:
1 2
The firstlinecontainstwo integers n,t。 The next n−1lines,eachlinecontainstwo integers x,y, indicating there is a corridor between the xth dormitory andthe yth dormitory.
输出描述:
1
An integer, indicating the latest timefor Orange tocatch Groundhog.
After t seconds, Groundhog is in the 5th dormitory and Orange is in the 7th dormitory.At this point, the best way for Groundhog istogoto the 2nd dormitory or the 6th6^{th}6th dormitory.But wherever he goes, he will be immediately caught by Orange.
备注:
1
1≤n≤105,1≤t≤n−1,1≤x,y≤n
思路
首先分析一下題目:有一棵树,A在1,B在2,A的移动速度是1边/s,B的是2边/s(可以选择走1边),前 t s A 在不断走向B,B不动。前 t s A在不断走向B,B是不动的,之后B就要开始移动逃离 A 了,求A最晚被追到的时间。
一棵树的两个结点之间的路径的基本是唯一的。所以可以把 B 为根,用LCA的ST倍增板子求A最后到达的位置。随后我们就要开始逃离,考虑A,B到达每一个点的情况,考虑A到达每个点所需要的时间,对于这个点,取两个时间中的较小值,取 A 和 B第 1 次到这个点的时间。然后从 A 出发寻找最大的二者到达时间相等的点。
usingnamespace std; typedef pair<int, int> PII; constint N = 1e5 + 10; int n, t; vector<int> P[N]; int fa[N][21]; bool st[N]; int ans = 0; int dist1[N], dist2[N];
voiddfs(int root, int place){ fa[root][0] = place; for (int i = 1; i <= 20; i++) fa[root][i] = fa[fa[root][i - 1]][i - 1]; for (auto &v : P[root]) { if (v != place) dfs(v, root); } }
intLCA(int u, int k){ int bit = 0; while (k) { if (k & 1) u = fa[u][bit]; k >>= 1; bit++; } return u; }
while (q.size()) { auto tt = q.front(); q.pop(); int k = tt.first, distance = tt.second; st[k] = true; for (int kkk: P[k]) { if (st[kkk]) continue; dist[kkk] = distance + 1; q.push({kkk, distance + 1}); } } }
voidbfs2(int kk){ memset(st, false, sizeof st); queue<int> q; q.push(kk); while (q.size()) { int k = q.front(); q.pop(); st[k] = true; ans = max(ans, max((dist2[k] + 1) / 2, dist1[k])); if ((dist2[k] + 1) / 2 <= dist1[k]) continue; for (int kkk : P[k]) { if (st[kkk]) continue; q.push(kkk); } } }
intmain() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin >> n >> t; for (int i = 0; i < n - 1; i++) { int a, b; cin >> a >> b; P[a].push_back(b); P[b].push_back(a); } // 1、下面利用LCA的DFS写法寻找到我们最终到达的结点位置 dfs(n, 0);