HDU 6203 ping ping ping(dfs序+LCA+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=6203
题意:
n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V
无法连通。问无法通行的点最少有多少个。
思路:
贪心思维,破坏两个点的LCA是最佳的。那么怎么判断现在在(u,v)之间的路径上有没有被破坏的点呢,如果没有的话那么此时就要破坏这个lca点。一开始我们要把询问按照u和v的lca深度从大到小排序,如果某个点需要被破坏,那么它的所有子节点都可以不再需要破坏别的点了(因为它的子节点到别的子节点肯定是要经过该点的,要注意这个前提是lca是排好序的,自己脑补一下~)。
所以,用dfs序来维护子节点是最好的,记录in和out两个数组。然后用树状数组来维护。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e4+; int n;
int Log;
int dfs_clock;
int in[maxn],out[maxn];
int deep[maxn];
int p[maxn][];
int c[*maxn];
vector<int> G[maxn]; struct node
{
int u,v,lca;
}query[]; void dfs(int u, int fa, int d)
{
in[u]=++dfs_clock;
deep[u]=d;
p[u][]=fa;
for(int i=;i<G[u].size();i++)
{
int v=G[u][i];
if(v==fa) continue;
dfs(v,u,d+);
}
out[u]=++dfs_clock;
} bool cmp(node a, node b)
{
return deep[a.lca]>deep[b.lca];
} void init()
{
for(int j=;j<=Log;j++)
for(int i=;i<=n;i++)
p[i][j]=p[p[i][j-]][j-];
} int LCA(int x, int y)
{
if(x==y) return x;
if(deep[x]<deep[y]) swap(x,y);
for(int i=Log;i>=;i--)
{
if(deep[p[x][i]]>=deep[y])
x=p[x][i];
}
if(x==y) return x;
for(int i=Log;i>=;i--)
{
if(p[x][i]!=p[y][i])
{
x=p[x][i];y=p[y][i];
}
}
return p[x][];
} int lowbit(int x)
{
return x&(-x);
} int sum(int x)
{
int ret = ;
while(x>)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
} void add(int x, int d)
{
while(x<=*n)
{
c[x]+=d;
x+=lowbit(x);
}
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
dfs_clock=;
memset(c,,sizeof(c));
memset(p,,sizeof(p));
for(int i=;i<=n+;i++) G[i].clear();
for(int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
u++;v++;
G[u].push_back(v);
G[v].push_back(u);
}
n++;
for(Log=;(<<Log)<=n;Log++);
Log--; dfs(,,);
init();
int q;
scanf("%d",&q);
for(int i=;i<=q;i++)
{
scanf("%d%d",&query[i].u,&query[i].v);
query[i].u++;query[i].v++;
query[i].lca=LCA(query[i].u,query[i].v);
}
sort(query+,query+q+,cmp);
int ans=;
for(int i=;i<=q;i++)
{
int u=query[i].u,v=query[i].v,lca=query[i].lca;
int tmp1=sum(in[u]),tmp2=sum(in[v]);
if(sum(in[u])+sum(in[v])) continue;
else
{
ans++;
add(in[lca],);
add(out[lca],-);
}
}
printf("%d\n",ans);
}
return ;
}
HDU 6203 ping ping ping(dfs序+LCA+树状数组)的更多相关文章
- BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...
- POJ 2763 Housewife Wind(DFS序+LCA+树状数组)
Housewife Wind Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 11419 Accepted: 3140 D ...
- HDU 3966 dfs序+LCA+树状数组
题目意思很明白: 给你一棵有n个节点的树,对树有下列操作: I c1 c2 k 意思是把从c1节点到c2节点路径上的点权值加上k D c1 c2 k 意思是把从c1节点到c2节点路径上的点权值减去k ...
- BZOJ 2819: Nim dfs序维护树状数组,倍增
1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...
- 【Tyvj2133&BZOJ1146】网络管理Network(树套树,DFS序,树状数组,主席树,树上差分)
题意:有一棵N个点的树,每个点有一个点权a[i],要求在线实现以下操作: 1:将X号点的点权修改为Y 2:查询X到Y的路径上第K大的点权 n,q<=80000 a[i]<=10^8 思路: ...
- 【BZOJ1103】大都市meg(DFS序,树状数组)
题意:有一颗树,1号点为根,保证编号小的点深度较小,初始状态每条边都没有被标记,要求实现两个操作在线: A:将连接x,y的边标记 W:查询从1到x的路径上有多少条边未被标记 n<=2*10^5 ...
- 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...
- 【POJ3321】Apple Tree(DFS序,树状数组)
题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 n,m<=100000 思路:最近一段时间在思考树上统计问题的算法 发 ...
- BZOJ 1103: [POI2007]大都市meg(dfs序,树状数组)
本来还想链剖的,结果才发现能直接树状数组的= = 记录遍历到达点与退出点的时间,然后一开始每个到达时间+1,退出时间-1,置为公路就-1,+1,询问直接点1到该点到达时间求和就行了- - CODE: ...
随机推荐
- create-react-app @observer装饰器报错
npm install --save-dev babel-plugin-transform-decorators-legacy 然后在node_modules/babel-preset-react-a ...
- [转载]对称加密DES和TripleDES
一. 对称加密 对称加密,是一种比较传统的加密方式,其加密运算.解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码).因此,通信双方都必须 ...
- IE haslayout的属性及其值
haslayout是IE 渲染引擎的一个内部组成部分.在IE 中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容.为了调节这两个不同的概念,渲染引擎采用了hasl ...
- html介绍和head标签
一.web标准 web准备介绍: w3c:万维网联盟组织,用来制定web标准的机构(组织) web标准:制作网页遵循的规范 web准备规范的分类:结构标准.表现标准.行为标准. 结构:html.表 ...
- shell中test命令方法详解
test命令用法.功能:检查文件和比较值 1)判断表达式 if test (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2 两个表达式 ...
- php 获取文件后缀
/** * 获取文件后缀 * $path 本地存储临时文件路径 * */ private function getFileType($path){ $fp=fopen($path,'r'); $bin ...
- Golang获取int数组里的最大值和下标
package main import ( "fmt" ) func main() { //获取一个数组里最大值,并且拿到下标 //声明一个数组5个元素 ], , , ,} //假 ...
- 程序连接oracle数据库问题Cannot create PoolableConnectionFactory ...
报错: [ERROR] -- :: com.ipi.caee.InitServlet - 初始化数据加载异常 org.springframework.transaction.CannotCreateT ...
- 判断一个点是否在RotatedRect中
openCV函数pointPolygonTest(): C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measur ...
- topcoder srm 686 div1
problem1 link 左括号和右括号较少的一种不会大于20.假设左括号少.设$f[i][mask][k]$表示处理了前$i$个字符,其中留下的字符以$k$开头($k=0$表示'(',$k=1$表 ...