HDU 6203 ping ping ping (LCA + 树状数组, 2017 ACM/ICPC Asia Regional Shenyang Online)
2017-09-11 09:19
453 查看
Problem
n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组U V无法连通。问无法通行的点最少有多少个。
Idea
根据所给的树(任意点为根)预处理出每个点的前序 DFS 序和后序 DFS 序(需统一标号),及点的深度。根据 p 组
U V处理每组两点的 LCA 。压入优先队列(LCA 深度大的点优先出队)。
对于出队的
U V及其对应的 LCA ,判断点 U 或点 V 是否在之前已禁止的某点的子树中。
判断点 U 或点 V 是否在之前已禁止的某点的子树中。
处理方式:由于之前已经处理出每个点的前后序 DFS 序 In[] 和 Out[] 。
对于某点 U 若在已禁止通行点 P 的子树中,则 In[P]≤In[U]≤Out[U]≤Out[P] 一定成立。
故利用树状数组区间更新单点查询。对每个禁止通行点 P ,标记区间 [In[P],Out[P]] 中所有点。查询时,若点 In[U] 被标记,则说明
U V已经被隔断。
同时,由于优先处理 LCA 深度大的点,不会出现点 U V 同时在同一个被禁止通行点 P 的子树内。
若 U ,V 均不在被禁止的点在子树内,则禁止
U V的 LCA 点,同时对答案贡献 +1 。
Code
#include<bits/stdc++.h> using namespace std; #define LL long long vector <int> g[10100]; int father[10100][22]={0}; int depth[10100]={0}; int bin[20200]; int In[10100]; int Out[10100]; int n,m; struct Node{ int u,v,uv; Node(){} Node(int _u,int _v,int _uv):u(_u),v(_v),uv(_uv){} friend bool operator<(Node n1,Node n2){ return depth[n1.uv]<depth[n2.uv]; } }; bool visit[10010]={false}; int root,cnt; void dfs(int u){ int i; visit[u]=true; In[u]=++cnt; for (i=0;i<g[u].size();i++){ int v=g[u][i]; if ( !visit[v] ){ depth[v]=depth[u]+1; father[v][0]=u; dfs(v); } } Out[u]=++cnt; } void bz(){ int i,j; for (j=1;j<=20;j++) for (i=1;i<=n;i++) father[i][j]=father[father[i][j-1]][j-1]; } int LCA(int u,int v) { if ( depth[u]<depth[v] ) { int temp=u; u=v; v=temp; } int dc=depth[u]-depth[v]; int i; for (i=0;i<=20;i++) { if ( (1<<i) & dc) u=father[u][i]; } if (u==v) return u; for (i=20;i>=0;i--){ if (father[u][i]!=father[v][i]) { u=father[u][i]; v=father[v][i]; } } u=father[u][0]; return u; } inline int lowbit(int x) { return x & -x; } inline int sum(int x) { int res = 0; while(x) res += bin[x], x -= lowbit(x);; return res; } inline void add(int x, int w) { while(x < 20200) bin[x] += w, x += lowbit(x); } inline int update(int x, int y, int w) { add(x, w); add(y+1, -w); } int main() { int u,v,p; while(scanf("%d", &n)!=EOF) { memset(bin,0,sizeof(bin)); memset(visit,0,sizeof(visit)); for(int i=0;i<=n+1;++i) g[i].clear(); for(int i=1;i<=n;++i){ scanf("%d %d",&u,&v); u++, v++; g[u].push_back(v); g[v].push_back(u); } n++; cnt=0; dfs(1); bz(); scanf("%d",&p); priority_queue<Node> q; while(!q.empty()) q.pop(); Node tmp; while(p--){ scanf("%d %d",&u,&v); u++; v++; int uv=LCA(u,v); tmp = Node(u,v,uv); q.push(tmp); } int ans=0; while(!q.empty()){ tmp=q.top(); q.pop(); int flg=sum(In[tmp.u])+sum(In[tmp.v]); if(!flg){ ans++; update(In[tmp.uv],Out[tmp.uv],1); } } printf("%d\n",ans); } }
相关文章推荐
- HDU 6201 transaction transaction transaction (Dijstra, 2017 ACM/ICPC Asia Regional Shenyang Online)
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1002-cable cable cable
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1005-number number number
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1001-string string string
- HDU - 6205 card card card (贪心)2017 ACM/ICPC Asia Regional Shenyang Online
- HDU 5877 Weak Pair 2016 ACM/ICPC Asia Regional Dalian Online(树状数组+离散化)
- HDU 6199 gems gems gems (DP, 2017 ACM/ICPC Asia Regional Shenyang Online)
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1004-array array array
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1008-transaction transaction transaction
- 2017 ACM/ICPC Asia Regional Shenyang Online Ping Ping Ping 树链剖分+树状数组
- 【2017 ACM/ICPC Asia Regional Shenyang Online 1002】hdu 6195 cable cable cable
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1012-card card card
- HDU 5452 Minimum Cut(LCA & RMQ & DFS)——2015 ACM/ICPC Asia Regional Shenyang Online
- 【HDU5892 2016 ACM ICPC Asia Regional Shenyang Online A】【二维树状数组模板 区间修改】nn矩阵内子矩阵中各怪兽数量的奇偶性.cpp
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-签到题
- HDU 6194 String String String (后缀数组+线段树, 2017 ACM/ICPC Asia Regional Shenyang Online)
- 2017 ACM/ICPC Asia Regional Shenyang Online 1001(hdu 6194)
- Hdu 5452 Minimum Cut (2015 ACM/ICPC Asia Regional Shenyang Online) dfs + LCA
- 【2017 ACM/ICPC Asia Regional Shenyang Online 1005】hdu 6198 number number number
- hdu 6206 模板题 2017 ACM/ICPC Asia Regional Qingdao Online