题意:一棵树,求不经过路径的最小标号
代码:
#include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; #define maxn 1005000 #define inf 0x3f3f3f3f int child[maxn][4]; int subtree[maxn]; int path[maxn]; int fa[maxn]; int bel[maxn]; int que[maxn]; int qh, qt; int n, nQ; int head[maxn]; int nxt[maxn<<1]; int vv[maxn<<1]; int tot; void add_Edge(int u,int v) { vv[tot] = v; nxt[tot] = head[u]; head[u] = tot++; } void bfs() { qh = qt = 0; que[qt++] = 1; fa[1] = -1; while (qh < qt){ int u = que[qh++]; for (int i = head[u]; ~i; i=nxt[i]){ int v = vv[i]; if (v == fa[u]) continue; fa[v] = u; que[qt++] = v; } } for (int i = 0; i <= n; ++i){ for (int j = 0; j < 4; ++j){ child[i][j] = inf; } } for (int i = n - 1; i >= 0; --i){ int u = que[i]; subtree[u] = u; for (int j = head[u]; ~j; j=nxt[j]){ int v = vv[j]; if (v == fa[u]) continue; child[u][3] = subtree[v]; sort(child[u], child[u] + 4); } subtree[u] = min(subtree[u], child[u][0]); } qh = qt = 0; for (int i = head[1]; ~i; i=nxt[i]){ int v = vv[i]; que[qt++] = v; bel[v] = subtree[v]; path[v] = inf; } while (qh < qt){ int u = que[qh++]; for (int i = head[u]; ~i; i=nxt[i]){ int v = vv[i]; if (v == fa[u]) continue; bel[v] = bel[u]; if (subtree[v] == child[u][0]){ path[v] = min(path[u], child[u][1]); } else{ path[v] = min(path[u], child[u][0]); } que[qt++] = v; } path[u] = min(path[u], child[u][0]); } } int query(int qu, int qv){ if (qu > qv) swap(qu, qv); if (qu != 1 && bel[qu] == bel[qv]) return 1; int i = 0; while (child[1][i] == bel[qu] || child[1][i] == bel[qv]){ i++; } int ret = qu == 1 ? path[qv] : min(path[qu], path[qv]); ret = min(ret, child[1][i]); return ret; } inline void scan(int &n) { char cc; for (; cc = getchar(), cc<‘0‘ || cc>‘9‘;); n = cc - ‘0‘; for (; cc = getchar(), cc >= ‘0‘&&cc <= ‘9‘;) n = n * 10 + cc - ‘0‘; } int main() { while (cin >> n >> nQ){ tot = 0; memset(head, -1, sizeof(head)); int ui, vi; for (int i = 0; i < n - 1; ++i){ //scan(ui); scan(vi); scanf("%d%d", &ui, &vi); add_Edge(ui, vi); add_Edge(vi, ui); } bfs(); int last = 0; for (int i = 0; i < nQ; ++i){ //scan(ui); scan(vi); scanf("%d%d", &ui, &vi); ui ^= last; vi ^= last; printf("%d\n", last=query(ui, vi)); } } return 0; }
时间: 2024-11-13 08:14:42