题目链接: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已经被隔断。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 20100;
  4. typedef long long LL;
  5. vector <int> G[maxn];
  6. int n, m, dfsclk, c[maxn], fa[maxn][21], dep[maxn], L[maxn], R[maxn];
  7. bool vis[maxn];
  8. struct node{
  9. int u,v,uv;
  10. node(){}
  11. node(int u,int v,int uv):u(u),v(v),uv(uv){}
  12. bool operator<(const node &rhs)const{
  13. return dep[uv]<dep[rhs.uv];
  14. }
  15. };
  16. void dfs(int x){
  17. vis[x]=1;
  18. L[x]=++dfsclk;
  19. for(int i=0; i<G[x].size(); i++){
  20. int v=G[x][i];
  21. if(!vis[v]){
  22. dep[v]=dep[x]+1;
  23. fa[v][0]=x;
  24. dfs(v);
  25. }
  26. }
  27. R[x]=++dfsclk;
  28. }
  29. void init(){
  30. for(int j=1; j<=20; j++)
  31. for(int i=1; i<=n; i++)
  32. fa[i][j] = fa[fa[i][j-1]][j-1];
  33. }
  34. int LCA(int u, int v){
  35. if(dep[u]<dep[v]) swap(u,v);
  36. for(int i=20; i>=0; i--){
  37. if((dep[u]-dep[v])&(1<<i))
  38. u=fa[u][i];
  39. }
  40. if(u==v) return u;
  41. for(int i=20; i>=0; i--){
  42. if(fa[u][i]!=fa[v][i]){
  43. u=fa[u][i];
  44. v=fa[v][i];
  45. }
  46. }
  47. return fa[u][0];
  48. }
  49. int lowbit(int x){
  50. return x&(-x);
  51. }
  52. void add(int x, int v){
  53. while(x<maxn){
  54. c[x]+=v;
  55. x+=lowbit(x);
  56. }
  57. }
  58. void update(int x, int y, int z){
  59. add(x, z);
  60. add(y+1, -z);
  61. }
  62. int query(int x){
  63. int ret=0;
  64. while(x>0){
  65. ret+=c[x];
  66. x-=lowbit(x);
  67. }
  68. return ret;
  69. }
  70. int main()
  71. {
  72. while(~scanf("%d", &n))
  73. {
  74. memset(c, 0, sizeof(c));
  75. memset(vis, 0, sizeof(vis));
  76. memset(dep, 0, sizeof(dep));
  77. for(int i=0; i<=n+1; i++) G[i].clear();
  78. for(int i=1; i<=n; i++){
  79. int u,v;
  80. scanf("%d %d", &u,&v);
  81. u++,v++;
  82. G[u].push_back(v);
  83. G[v].push_back(u);
  84. }
  85. n++;
  86. dfsclk = 0;
  87. dfs(1);
  88. init();
  89. priority_queue <node> q;
  90. scanf("%d", &m);
  91. while(m--){
  92. int u, v;
  93. scanf("%d %d", &u,&v);
  94. u++;
  95. v++;
  96. int uv = LCA(u, v);
  97. q.push(node(u,v,uv));
  98. }
  99. int ans=0;
  100. while(!q.empty()){
  101. node now = q.top();
  102. q.pop();
  103. int flag = query(L[now.u])+query(L[now.v]);
  104. if(flag==0){
  105. ans++;
  106. update(L[now.uv],R[now.uv],1);
  107. }
  108. }
  109. printf("%d\n", ans);
  110. }
  111. return 0;
  112. }

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. 【BZOJ 3652】大新闻 数位dp+期望概率dp

    并不难,只是和期望概率dp结合了一下.稍作推断就可以发现加密与不加密是两个互相独立的问题,这个时候我们分开算就好了.对于加密,我们按位统计和就好了;对于不加密,我们先假设所有数都找到了他能找到的最好的 ...

  2. 一些$LCT$的瓜皮题目

    一些瓜皮 放几个比较优(she)秀(pi)的\(LCT\)题. 老惯例,每一题代码因为一些未知原因消失了(如果要的话私我好了,虽然会咕咕咕). 嘴巴\(AC\)真香! [SP16580] QTREE7 ...

  3. Jump Game - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Jump Game - LeetCode 注意点 解法 解法一:贪心算法,只关注能到达最远距离,如果能到达的最远距离大于结尾说明能到达,否则不能.并且如果 ...

  4. BZOJ3522 [Poi2014]Hotel 【树形dp】

    题目链接 BZOJ3522 题解 就是询问每个点来自不同子树离它等距的三个点的个数 数据支持\(O(n^2)\),可以对每个距离分开做 设\(f[i][j]\)表示\(i\)的子树中到\(i\)距离为 ...

  5. 洛谷 P1341 无序字母对 解题报告

    P1341 无序字母对 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 ...

  6. 【bzoj3122】 Sdoi2013—随机数生成器

    http://www.lydsy.com/JudgeOnline/problem.php?id=3122 (题目链接) 题意 对于一个数列${X_i}$,其递推式为:${X_{i+1}=(a*X_i+ ...

  7. 使用regsrv32.exe绕过应用程序白名单(多种方法)

    0x00 regsvr简介 regsvr32表示Microsoft注册服务.它是Windows的命令行实用工具.虽然regsvr32有时会导致问题出现,但它是Windows系统文件中的一个重要文件.该 ...

  8. 20165218 《网络对抗技术》Exp3 免杀原理与实践

    Exp3 免杀原理与实践 任务一:正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编程等免杀工具或技巧 使用VirusTotal或 ...

  9. 解题:NOI 2016 优秀的拆分

    题面 其实题目不算很难,但是我调试的时候被玄学了,for循环里不写空格会RE,写了才能过.神**调了一个多小时是这么个不知道是什么的玩意(真事,可以问i207M=.=),心态爆炸 发现我们只要找AA或 ...

  10. LGP4588[JSOI2018]扫地机器人

    题解 需要先说明一点东西: 1 同一副对角线方向相同,共有$gcd(n,m)$条不同的副对角线,机器人的行为是一个$gcd(n,m)$的循环:: 如果左上方是$(1,1)$,容易看出所有的路径是从左或 ...