Codeforces 519E A and B and Lecture Rooms LCA

题目链接:点击打开链接

题意:

给定n个点的树。

下面n-1行给出树

Q个询问。

每次询问 (u,v)问树上有多少个点到u点距离=到v点距离

思路:

首先这两个点的距离必须是偶数,若为奇数答案就是0

然后用lca找到中间节点即可。

trick : u==v ans = n

#include"cstdio"#include"iostream"#include"queue"#include"algorithm"#include"set"#include"queue"#include"cmath"#include"string.h"#include"vector"using namespace std;template <class T>inline bool rd(T &ret) {char c; int sgn;if (c = getchar(), c == EOF) return 0;while (c != '-' && (c<'0' || c>'9')) c = getchar();sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c – '0');while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c – '0');ret *= sgn;return 1;}template <class T>inline void pt(T x) {if (x <0) {putchar('-');x = -x;}if (x>9) pt(x / 10);putchar(x % 10 + '0');}#define N 100500struct Edge{int from, to, nex;}edge[2 * N];int head[N], edgenum, fa[N][20], dep[N], siz[N]; //fa[i][x] 是i的第2^x个父亲(如果超过范围就是根)void add(int u, int v){Edge E = { u, v, head[u] };edge[edgenum] = E;head[u] = edgenum++;}void bfs(int root){queue<int> q;fa[root][0] = root; dep[root] = 0; siz[root] = 0;q.push(root);while (!q.empty()){int u = q.front(); q.pop();for (int i = 1; i<20; i++)fa[u][i] = fa[fa[u][i – 1]][i – 1];for (int i = head[u]; ~i; i = edge[i].nex){int v = edge[i].to; if (v == fa[u][0])continue;dep[v] = dep[u] + 1; fa[v][0] = u;q.push(v);}}}void dfs(int u, int f){siz[u] = 1;for (int i = head[u]; ~i; i = edge[i].nex){int v = edge[i].to; if (v == f)continue;dfs(v, u);siz[u] += siz[v];}}int Lca(int x, int y){if (dep[x]<dep[y])swap(x, y);for (int i = 0; i<20; i++)if ((dep[x] – dep[y])&(1 << i))x = fa[x][i];if (x == y)return x;for (int i = 19; i >= 0; i–)if (fa[x][i] != fa[y][i])x = fa[x][i], y = fa[y][i];return fa[x][0];}void init(){ memset(head, -1, sizeof head); edgenum = 0; }int n, m;int go(int D, int x){while (D){int z = log10(1.0*D) / log10(2.0);x = fa[x][z];D -= 1 << z;}return x;}int main(){rd(n);init();for (int i = 1, u, v; i < n; i++){rd(u); rd(v);add(u, v); add(v, u);}bfs(1);dfs(1, 1);rd(m);int x, y;while (m–){rd(x); rd(y);if (x == y){ pt(n); putchar('\n'); continue; }if (dep[x]>dep[y])swap(x, y);int l = Lca(x, y);int len = dep[x] – dep[l] + dep[y] – dep[l];if (len & 1){putchar('0');}else {len = len / 2 – 1;int a = go(len, y), b = fa[a][0];if (b == l){pt(n – siz[a] – siz[go(len, x)]);}else pt(siz[b] – siz[a]);}putchar('\n');}return 0;}

,理想的路总是为有信心的人预备着

Codeforces 519E A and B and Lecture Rooms LCA

相关文章:

你感兴趣的文章:

标签云: