HDU 6203 ping ping ping LCA + dfs序 + 树状数组(区间更新单点查询)
来源:互联网 发布:2017淘宝双11技术汇总 编辑:程序博客网 时间:2024/05/16 09:13
传送门:HDU 6203
题意:给出n+1 个点的树,其中有若干个点无法通过,导致 p 组顶点对(u, v)之间无法连通。问无法通行的点最少有多少个。
思路:对p组(u,v)顶点对求LCA,并按LCA的深度排序,从深度最大的开始处理,然后在dfs序上进行标记,若当前顶点对之间已经不可达,则直接跳过,否则将其LCA在dfs序上标记出来。
具体标记及判断方法详见:点击打开链接
树状数组区间更新单点查询就很类似于imos和思想,也很常用。
代码:
#include<bits/stdc++.h> using namespace std; #define MAXN 10050#define MAXM 10050#define inf 0x3f3f3f3f typedef pair<int,int>P; int dep[MAXN], pre_ord[MAXN], post_ord[MAXN];int f[20][MAXN], pre[MAXN]; int cnt, tid; struct node { int v, next; node(int _v = 0, int _next = 0) : v(_v), next(_next) {} }mp[MAXM * 2]; void init() { cnt = tid = 0; memset(pre, -1, sizeof(pre));}void add(int u, int v) { mp[cnt] = node(v, pre[u]), pre[u] = cnt++; mp[cnt] = node(u, pre[v]), pre[v] = cnt++;} void dfs(int u, int fa) { dep[u] = dep[fa] + 1; pre_ord[u] = ++tid; for(int i = pre[u]; ~i; i = mp[i].next) { int v = mp[i].v; if(v == fa) continue; dfs(v, u); f[0][v] = u; } post_ord[u] = ++tid;} int lca_init(int n) { dep[1] = 1; dfs(1, 0); int k = 0,t = 1; while(t <= n)t <<= 1,k++; for(int i=0;i+1<k;i++) { for(int j=1;j<=n;j++) { f[i+1][j] = f[i][f[i][j]]; } } return k; }int lca(int u, int v, int MAX) { if(dep[u] < dep[v]) swap(u, v); int k = dep[u] - dep[v]; for(int i = 0;i < MAX; i++) { if((k >> i) & 1) u = f[i][u]; } if(u == v)return u; for(int i = MAX - 1;i >= 0; i--) while(f[i][u] != f[i][v]) { u = f[i][u]; v = f[i][v]; } return f[0][u]; }struct query{ int u, v, lca; query(int _u = 0, int _v = 0, int _lca = 0) : u(_u), v(_v), lca(_lca) {} bool operator < (query x) const { return dep[lca] > dep[x.lca]; }}Q[MAXN * 5];int bit[MAXN << 1];void update(int i, int x){ while(i <= tid) { bit[i] += x; i += i & -i; }}int sum(int i){ int res = 0; while(i) { res += bit[i]; i -= i & -i; } return res;}int main(){ int T, n, u, v, q; while(~scanf("%d", &n)) { init(); memset(bit, 0, sizeof(bit)); for(int i = 1; i <= n; i++) { scanf("%d %d", &u, &v); add(++u, ++v); } n++; int up = lca_init(n); scanf("%d", &q); for(int i = 0; i < q; i++) { scanf("%d %d", &u, &v); u++,v++; Q[i] = query(u, v, lca(u, v, up)); } sort(Q, Q + q); int is, ans = 0; for(int i = 0; i < q; i++) { is = sum(pre_ord[Q[i].u]) + sum(pre_ord[Q[i].v]); if(!is) { ans++; update(pre_ord[Q[i].lca], 1); update(post_ord[Q[i].lca] + 1, -1); } } cout << ans << endl; } return 0;}
阅读全文
0 0
- HDU 6203 ping ping ping LCA + dfs序 + 树状数组(区间更新单点查询)
- HDU 6203 ping ping ping [LCA+dfs序+树状数组]
- Hdu 6203 ping ping ping dfs序+树状数组维护
- HDU 6203 ping ping ping (LCA+DFS序)
- HDU 6203 ping ping ping (LCA + 树状数组, 2017 ACM/ICPC Asia Regional Shenyang Online)
- HDU 6203 ping ping ping lca 线段树成段更新
- HDU 6203ping ping ping(LCA+贪心)
- [HDU 6203] ping ping ping
- HDU 6203 ping ping ping
- hdu 2492 Ping pong(树状数组)
- hdu 2492 Ping pong (树状数组)
- HDU 2492 Ping pong (树状数组)
- hdu 2492 Ping pong(树状数组)
- hdu-2492-Ping pong(树状数组)
- HDU 2492 Ping pong(树状数组)
- HDU 2492 Ping pong(树状数组)
- hdu 4533(树状数组区间更新+单点查询)
- Ping pong(树状数组)
- PHP之static静态变量详解(一)
- 【系统学习SpringBoot】SpringBoot定时任务详解
- 全网营销不单单局限于seo
- hdu 6201 transaction transaction transaction
- 大话推荐系统
- HDU 6203 ping ping ping LCA + dfs序 + 树状数组(区间更新单点查询)
- 笔记8 | 系统时间设置界面DatePickerDialog,TimePickerDialog,DatePicker
- JAVA RESTful WebService实战笔记(三)
- leetcode
- Java反射
- php自学day1
- Bootstrap插件(二)——滚动监听(scrollspy.js)
- 计算机网络与OSI七层模型
- lintcode.68 二叉树后序遍历