题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203

题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连通。问无法通行的点最少有多少个。

解法:按照询问的LCA深度排序,然后顺序标记每个询问的LCA。根据所给的树(任意点为根)预处理出每个点的前序 DFS 序和后序 DFS 序(需统一标号),及点的深度。根据 p 组 U V 处理每组两点的 LCA 。压入优先队列(LCA 深度大的点优先出队)。对于出队的 U V 及其对应的 LCA ,判断点 U 或点 V 是否在之前已禁止的某点的子树中,对于某点U如果在禁止通行的点P的子树中,则L[P]<=L[U]<=R[U]<=R[P]一定成立。所以可以利用树状数组区间更新单点查询,对于每个禁止通行点标记区间L[P],R[P]的所有节点。查询的时候如果L[U]被标记,说明U,V已经被隔断。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 20100;
typedef long long LL;
vector <int> G[maxn];
int n, m, dfsclk, c[maxn], fa[maxn][21], dep[maxn], L[maxn], R[maxn];
bool vis[maxn];
struct node{
int u,v,uv;
node(){}
node(int u,int v,int uv):u(u),v(v),uv(uv){}
bool operator<(const node &rhs)const{
return dep[uv]<dep[rhs.uv];
}
};
void dfs(int x){
vis[x]=1;
L[x]=++dfsclk;
for(int i=0; i<G[x].size(); i++){
int v=G[x][i];
if(!vis[v]){
dep[v]=dep[x]+1;
fa[v][0]=x;
dfs(v);
}
}
R[x]=++dfsclk;
}
void init(){
for(int j=1; j<=20; j++)
for(int i=1; i<=n; i++)
fa[i][j] = fa[fa[i][j-1]][j-1];
}
int LCA(int u, int v){
if(dep[u]<dep[v]) swap(u,v);
for(int i=20; i>=0; i--){
if((dep[u]-dep[v])&(1<<i))
u=fa[u][i];
}
if(u==v) return u;
for(int i=20; i>=0; i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
}
return fa[u][0];
}
int lowbit(int x){
return x&(-x);
}
void add(int x, int v){
while(x<maxn){
c[x]+=v;
x+=lowbit(x);
}
}
void update(int x, int y, int z){
add(x, z);
add(y+1, -z);
}
int query(int x){
int ret=0;
while(x>0){
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
int main()
{
while(~scanf("%d", &n))
{
memset(c, 0, sizeof(c));
memset(vis, 0, sizeof(vis));
memset(dep, 0, sizeof(dep));
for(int i=0; i<=n+1; i++) G[i].clear();
for(int i=1; i<=n; i++){
int u,v;
scanf("%d %d", &u,&v);
u++,v++;
G[u].push_back(v);
G[v].push_back(u);
}
n++;
dfsclk = 0;
dfs(1);
init();
priority_queue <node> q;
scanf("%d", &m);
while(m--){
int u, v;
scanf("%d %d", &u,&v);
u++;
v++;
int uv = LCA(u, v);
q.push(node(u,v,uv));
}
int ans=0;
while(!q.empty()){
node now = q.top();
q.pop();
int flag = query(L[now.u])+query(L[now.v]);
if(flag==0){
ans++;
update(L[now.uv],R[now.uv],1);
}
}
printf("%d\n", ans);
}
return 0;
}

HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组的更多相关文章

  1. HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Tota ...

  2. HDU - 6393 Traffic Network in Numazu (LCA+RMQ+树状数组)

    这道题相当于将这两题结合: http://poj.org/problem?id=2763 http://codeforces.com/gym/101808/problem/K 题意:有N各点N条边的带 ...

  3. HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...

  4. HDU 6200 2017沈阳网络赛 树上区间更新,求和

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6200 题意:给个图,有2种操作,一种是加一条无向边,二是查询u,v之间必须有的边的条数,所谓必须有的边 ...

  5. HDU 6199 2017沈阳网络赛 DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6199 题意:n堆石子,Alice和Bob来做游戏,一个人选择取K堆那么另外一个人就必须取k堆或者k+1 ...

  6. HDU 6205 2017沈阳网络赛 思维题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6205 题意:给你n堆牌,原本每一堆的所有牌(a[i]张)默认向下,每次从第一堆开始,将固定个数的牌(b ...

  7. HDU 6198 2017沈阳网络赛 线形递推

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198 题意:给出一个数k,问用k个斐波那契数相加,得不到的数最小是几. 解法:先暴力打表看看有没有规律 ...

  8. HDU 6195 2017沈阳网络赛 公式

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6195 题意:有M个格子,有K个物品.我们希望在格子与物品之间连数量尽可能少的边,使得——不论是选出M个 ...

  9. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

随机推荐

  1. [BZOJ2288&BZOJ1150]一类堆+链表+贪心问题

    今天我们来介绍一系列比较经典的堆+链表问题.这类问题的特点是用堆选取最优解,并且通过一些加减操作来实现"反悔". 在看题之前,我们先来介绍一个神器:手写堆. 手写堆的一大好处就是可 ...

  2. H5页面遮罩弹框下层还能滚动的问题

    在页面上显示一个遮罩层,这是非常常见的操作,在遮罩层上操作,下层也会默认跟随手指滚动 此处就是要在显示遮罩的时候禁止下层滚动. 首先设置一个全局变量 var canScroll=false; 页面初始 ...

  3. 解决Android SDK Manager更新时出现问题

    使用SDK Manager更新时出现问题Failed to fetch URL https://dl-ssl.google.com/android/repository/repository-6.xm ...

  4. Chapter6(函数) --C++Prime笔记

    1.重载函数,也就是说一个名字可以对应几个不同的函数. 2.内置类型的未初始化局部变量将产生未定义的值. 3.局部静态对象在程序执行路径第一次进过对象定义语句时初始化,并且直到程序终止才被销毁. 内置 ...

  5. 将SQL Server账户对应到Windows系统账户

    应用场景举例: SQL Server账户要访问外部资源,例如所拥有的Job要访问文件系统,而此文件系统需要Windows账户才有权限. 步骤: 1.       服务器新建凭据(Credentials ...

  6. Docker入门与应用系列(四)数据卷管理

    一.介绍 Docker镜像是由多个文件系统(只读层)叠加而成.当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(译者注:镜像栈顶部)添加一个读写层.如果运行中的容器修改了现有的一个已经存 ...

  7. mysql 设置默认编码为 utf8

    vi /etc/mysql/mysql.conf.d/mysqld.cnf [client] default-character-set=utf8 [mysql] default-character- ...

  8. Java基础-Collection子接口之Set接口

    Java基础-Collection子接口之Set接口 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 学习Collection接口时,记得Collection中可以存放重复元素,也可 ...

  9. 模块型css样式

    <div id="dowork"> <div id="dowork_on">۞作业进行中</div> <div id= ...

  10. POJ 3308 Paratroopers(最小点权覆盖)(对数乘转加)

    http://poj.org/problem?id=3308 r*c的地图 每一个大炮可以消灭一行一列的敌人 安装消灭第i行的大炮花费是ri 安装消灭第j行的大炮花费是ci 已知敌人坐标,同时消灭所有 ...