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+树状数组)的更多相关文章

  1. BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...

  2. POJ 2763 Housewife Wind(DFS序+LCA+树状数组)

    Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11419   Accepted: 3140 D ...

  3. HDU 3966 dfs序+LCA+树状数组

    题目意思很明白: 给你一棵有n个节点的树,对树有下列操作: I c1 c2 k 意思是把从c1节点到c2节点路径上的点权值加上k D c1 c2 k 意思是把从c1节点到c2节点路径上的点权值减去k ...

  4. BZOJ 2819: Nim dfs序维护树状数组,倍增

    1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...

  5. 【Tyvj2133&BZOJ1146】网络管理Network(树套树,DFS序,树状数组,主席树,树上差分)

    题意:有一棵N个点的树,每个点有一个点权a[i],要求在线实现以下操作: 1:将X号点的点权修改为Y 2:查询X到Y的路径上第K大的点权 n,q<=80000 a[i]<=10^8 思路: ...

  6. 【BZOJ1103】大都市meg(DFS序,树状数组)

    题意:有一颗树,1号点为根,保证编号小的点深度较小,初始状态每条边都没有被标记,要求实现两个操作在线: A:将连接x,y的边标记 W:查询从1到x的路径上有多少条边未被标记 n<=2*10^5 ...

  7. 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)

    4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...

  8. 【POJ3321】Apple Tree(DFS序,树状数组)

    题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 n,m<=100000   思路:最近一段时间在思考树上统计问题的算法 发 ...

  9. BZOJ 1103: [POI2007]大都市meg(dfs序,树状数组)

    本来还想链剖的,结果才发现能直接树状数组的= = 记录遍历到达点与退出点的时间,然后一开始每个到达时间+1,退出时间-1,置为公路就-1,+1,询问直接点1到该点到达时间求和就行了- - CODE: ...

随机推荐

  1. LoadRunner录制登录机票网址,并回放,加断言

    回放录制登录过程脚本,加断言 在页面登录的过程如下: 1先进入http://127.0.0.1:1080/WebTours/index.htm 2之后获取userSession信息 3在输入信息后点击 ...

  2. Linux基础命令---文本显示tac

    tac 将指定文件中的行,按照反序方式显示.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法         tac [选项] ...

  3. 新做了块avr开发板--tft屏研究用

    2010-05-04 14:03:00 测试效果不错,使用也方便.

  4. right spindle supply short to gnd-- compact version

    hardware guy found that the R1004 lead to this error, but this error should not be checked, because ...

  5. Redis Desktop Manager连接Redis

    1.注释redis.conf文件中的:bind 127.0.0.1修改为自己的IP 2.ifconfig查看自己的虚拟机ip 3.拿到IP后,返回Windows,开启cmd,通过telnet命令,测试 ...

  6. vs2015 dx15开发教程一

  7. rman备份例子

    1.全备份例子 #!/bin/sh RMAN_OUTPUT_LOG=/home/oracle/rman_output.logRMAN_ERROR_LOG=/home/oracle/rman_error ...

  8. 记录结果再利用的"动态规划"之背包问题

    参考<挑战程序设计竞赛>p51 https://www.cnblogs.com/Ymir-TaoMee/p/9419377.html 01背包问题 问题描述:有n个重量和价值分别为wi.v ...

  9. os模块,os.path模块,subprocess模块,configparser模块,shutil模块

    1.os模块 os表示操作系统该模块主要用来处理与操作系统相关的操作最常用的文件操作打开 读入 写入 删除 复制 重命名 os.getcwd() 获取当前执行文件所在的文件夹路径os.chdir(&q ...

  10. PyCharm笔记之首次安装和激活

    转载:http://www.cnblogs.com/Ivyli4258/p/7440147.html PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其 ...