[HDU 6203] ping ping ping
2017-09-11 14:20
357 查看
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6203
题意:给出一棵树, 给出p组点对(u, v), 求删除最少的点使得这p组点对均不联通。(n≤104,p≤2∗104)
思路:处理出每组点对的lca,按lca的深度从大到小依次考虑, 如果u, v均没有被标记, 则标记lca子树内的所有点, 答案+1。
时间复杂度:O(nlogn)
题意:给出一棵树, 给出p组点对(u, v), 求删除最少的点使得这p组点对均不联通。(n≤104,p≤2∗104)
思路:处理出每组点对的lca,按lca的深度从大到小依次考虑, 如果u, v均没有被标记, 则标记lca子树内的所有点, 答案+1。
时间复杂度:O(nlogn)
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #define ls (x << 1) #define rs (x << 1 | 1) #define mid ((l + r) >> 1) using namespace std; const int N = (int)5e4 + 10; int n; int cnt, lst , to[N * 2], nxt[N * 2]; void add(int u, int v){ nxt[++ cnt] = lst[u]; lst[u] = cnt; to[cnt] = v; nxt[++ cnt] = lst[v]; lst[v] = cnt; to[cnt] = u; } int indx, L , R , fa [20], dep ; void dfs(int u, int pre){ L[u] = ++ indx; fa[u][0] = pre; dep[u] = dep[pre] + 1; for (int j = lst[u]; j; j = nxt[j]){ int v = to[j]; if (v == pre) continue; dfs(v, u); } R[u] = indx; } int lca(int u, int v){ if (dep[u] < dep[v]) swap(u, v); for (int k = dep[u] - dep[v], j = 0; k; j ++, k >>= 1) if (k & 1) u = fa[u][j]; if (u == v) return u; for (int j = 19; j >= 0; j --) if (fa[u][j] != fa[v][j]) u = fa[u][j], v = fa[v][j]; return fa[u][0]; } int bj[N << 1], query [3], id ; void build(int x, int l, int r){ bj[x] = 0; if (l == r) return; build(ls, l, mid); build(rs, mid + 1, r); } bool cmp(int i, int j){ return dep[query[i][2]] > dep[query[j][2]]; } bool ask(int x, int l, int r, int pos){ if (bj[x]) return 1; if (l == r) return 0; if (pos <= mid) return ask(ls, l, mid, pos); return ask(rs, mid + 1, r, pos); } void modf(int x, int l, int r, int L, int R){ if (l == L && r == R){ bj[x] = 1; return; } if (R <= mid) return modf(ls, l, mid, L, R); if (L > mid) return modf(rs, mid + 1, r, L, R); return modf(ls, l, mid, L, mid), modf(rs, mid + 1, r, mid + 1, R); } int main(){ while (scanf("%d", &n) != EOF){ cnt = 0; n ++; for (int i = 1; i <= n; i ++) lst[i] = 0; for (int i = 1, u, v; i < n; i ++){ scanf("%d %d", &u, &v); u ++; v ++; add(u, v); } indx = 0; dfs(1, 0); for (int j = 1; j < 20; j ++) for (int i = 1; i <= n; i ++) fa[i][j] = fa[fa[i][j - 1]][j - 1]; build(1, 1, n); int p; scanf("%d", &p); for (int i = 1, u, v; i <= p; i ++){ scanf("%d %d", &u, &v); u ++; v ++; query[i][0] = u, query[i][1] = v, query[i][2] = lca(u, v); } for (int i = 1; i <= p; i ++) id[i] = i; sort(id + 1, id + p + 1, cmp); int ans = 0; for (int i = 1; i <= p; i ++){ int u = query[id[i]][0], v = query[id[i]][1], Lca = query[id[i]][2]; bool ok = ask(1, 1, n, L[u]) || ask(1, 1, n, L[v]); if (!ok) ans ++, modf(1, 1, n, L[Lca], R[Lca]); } printf("%d\n", ans); } return 0; }
相关文章推荐
- HDU 6203 ping ping ping(在线倍增LCA+BIT)
- hdu 6203 ping ping ping(LCA+树状数组)
- HDU 6203 ping ping ping (LCA+DFS序)
- hdu 6203 ping ping ping(贪心+树状数组+dfs序)
- HDU 6203 ping ping ping(dfs序+LCA+树状数组)
- HDU 6203 ping ping ping [LCA+dfs序+树状数组]
- HDU 6203 ping ping ping lca 线段树成段更新
- HDU 6203 ping ACM/ICPC 2017 Shenyang Online(LCA+贪心)
- HDU 6203 ping ping ping (LCA + 树状数组, 2017 ACM/ICPC Asia Regional Shenyang Online)
- HDU 6203 ping ping ping
- hdu Ping pong Ping pong 线段树
- POJ 3928 & hdu 2492 & Uva1428 PingPong 【树状数组】
- pku hdu pingpong
- POJ 3928 & hdu 2492 & Uva1428 PingPong 【树状数组】
- HDU 6203 贪心 + LCA + dfs序 + BIT
- Hdu 6203 ping ping ping dfs序+树状数组维护
- HDU - 6203 ping ping ping LCA倍增算法+dfs序+线段树
- HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组
- HDU 6203 ping ping ping LCA + dfs序 + 树状数组(区间更新单点查询)
- HDU 4331 Image Recognition