HDU 6203 ping ping ping(贪心+LCA+DFS序+BIT)
ping ping ping
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 207 Accepted Submission(s): 47
The structure of the computer room in Northeastern University is pretty miraculous. There are n servers, some servers connect to the gateway whose IP address is 0 directly. All servers are connected with each other by n netting twines. It is said that this structure is favorable for maintaining physical problem of servers.
But because of an unexpected rainstorm, the computer room was destroyed by a terrible thunderclap!
Our maintainer Bittersweet found that many servers were not able to be visited, so he hurried to the computer room to lookup the reason. After several hours, Bittersweet realized that some net gape of servers were broken by thunderclap. However, there were too many servers to find out all the broken net gapes quickly. So he came up with an idea to assess the damaged condition roughly. Bittersweet decided to turn on some servers and ping other servers randomly, then record the unsuccessful pairs of servers.
Now he need a program to analyze the record to confirm what is the minimum number of servers whose net gape was destroyed by thunderclap. Can you help him to complete this work?
There are at most 20 test cases.
In each test case, the first line is an integer n (3≤n≤104), denoting the number of servers. The IP address of these servers is 1…n.
Then follows n lines, each line contains two integers u and v (0≤u,v≤n), denoting that the server whose IP address is u is connected with the server whose IP address is v by netting twine initially.
After those, there is one line contains only an integer p (p≤50000), denoting the number that Bittersweet uses ping.
Then follows p lines, each line contains two integers U and V , denoting when using server U to ping server V, it returned unsuccessful.
题目链接:HDU 6203
题意就是求最少的点覆盖所有给定的q条路径,其实可以转换一下,就是求最多的路径集合使得集合内的路径两两之间不存在交点,那么跟HDU 4912是一样的题目了,先把所有路径按照其LCA深度从大到小排,即先处理靠下方的,因为这样对其他路径影响肯定是最小的,然后看这条路径的两端$u$和$v$是否被标记过,如果没标记就把以$LCA(u,v)$为根的子树全部标记上,否则就说明这条路径至少与其他路径存在一个交点(被标记的点)以此类推,如何快速标记子树呢?DFS序啊,而且子树是区间更新,查询端点是点查询,用BIT刚刚好
代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 10010;
const int M = 50010;
struct edge
{
int to, nxt;
edge() {}
edge(int _to, int _nxt): to(_to), nxt(_nxt) {}
} E[N << 1];
int head[N], tot;
struct info
{
int u, v, lca, dep;
bool operator<(const info &rhs)const
{
return dep > rhs.dep;
}
} node[M];
int D[N << 1], F[N], ver[N << 1], dp[N << 1][19], ts, dep[N];
int T[N], L[N], R[N], idx; void init()
{
CLR(head, -1);
tot = 0;
ts = 0;
CLR(T, 0);
idx = 0;
}
inline void add(int s, int t)
{
E[tot] = edge(t, head[s]);
head[s] = tot++;
}
void dfs(int u, int f, int d)
{
ver[++ts] = u;
D[ts] = d;
F[u] = ts; L[u] = ++idx;
dep[u] = d;
for (int i = head[u]; ~i; i = E[i].nxt)
{
int v = E[i].to;
if (v != f)
{
dfs(v, u, d + 1);
ver[++ts] = u;
D[ts] = d;
}
}
R[u] = idx;
}
void RMQ_init(int l, int r)
{
int i, j;
for (i = l; i <= r; ++i)
dp[i][0] = i;
for (j = 1; l + (1 << j) - 1 <= r; ++j)
{
for (i = l; i + (1 << j) - 1 <= r; ++i)
{
int a = dp[i][j - 1], b = dp[i + (1 << (j - 1))][j - 1];
dp[i][j] = D[a] < D[b] ? a : b;
}
}
}
int LCA(int u, int v)
{
int l = F[u], r = F[v];
if (l > r)
swap(l, r);
int len = r - l + 1;
int k = 0;
while (1 << (k + 1) <= len)
++k;
int a = dp[l][k], b = dp[r - (1 << k) + 1][k];
return D[a] < D[b] ? ver[a] : ver[b];
}
namespace BIT
{
void add(int k, int v)
{
while (k < N)
{
T[k] += v;
k += (k & -k);
}
}
int sum(int k)
{
int ret = 0;
while (k)
{
ret += T[k];
k -= (k & -k);
}
return ret;
}
}
int main(void)
{
int n, u, v, i, q;
while (~scanf("%d", &n))
{
init();
for (i = 0; i < n; ++i)
{
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs(0, -1, 0);
RMQ_init(1, ts);
scanf("%d", &q);
for (i = 0; i < q; ++i)
{
scanf("%d%d", &node[i].u, &node[i].v);
node[i].lca = LCA(node[i].u, node[i].v);
node[i].dep = dep[node[i].lca];
}
sort(node, node + q);
int ans = 0;
for (i = 0; i < q; ++i)
{
if (BIT::sum(L[node[i].u]) || BIT::sum(L[node[i].v]))
continue;
BIT::add(L[node[i].lca], 1);
BIT::add(R[node[i].lca] + 1, -1);
++ans;
}
printf("%d\n", ans);
}
return 0;
}
HDU 6203 ping ping ping(贪心+LCA+DFS序+BIT)的更多相关文章
- 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)
题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- HDU 4358 Boring counting(莫队+DFS序+离散化)
Boring counting Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 98304/98304 K (Java/Others) ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- bzoj3991 lca+dfs序应用+set综合应用
/* 给定一棵树,树上会出现宝物,也会有宝物消失 规定如果要收集树上所有宝物,就要选择一个点开始,到每个宝物点都跑一次,然后再回到那个点 现在给定m次修改,每次修改后树上就有一个宝物消失,或者一个宝物 ...
- BZOJ3881[Coci2015]Divljak——AC自动机+树状数组+LCA+dfs序+树链的并
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- nowcoder172C 保护 (倍增lca+dfs序+主席树)
https://www.nowcoder.com/acm/contest/172/C (sbw大佬太强啦 orz) 先把每一个路径(x,y)分成(x,lca),(y,lca)两个路径,然后就能发现,对 ...
随机推荐
- 汇编:将指定的内存中连续N个字节填写成指定的内容
1.loop指令实现 ;=============================== ;循环程序设计 ;将制定内存中连续count个字节填写成指定内容(te) ;loop指令实现 DATAS SEG ...
- 6 大主流 Web 框架优缺点对比(转)
英文: Kit Kelly 译文:oschina https://www.oschina.net/translate/web-frameworks-conclusions 是该读些评论和做一些总结 ...
- mysql 导出数据字典
使用Navicat工具 查询: SELECT TABLE_SCHEMA AS '数据库', TABLE_NAME AS '表名', COLUMN_NAME AS '字段名', COLUMN_TYPE ...
- linux总结及常用命令
一.操作系统的作用: 1.是现代计算机系统中最基本和最重要的系统软件 2.承上启下的作用 3.向下对硬件操作进行封装 4.向上对用户和应用程序提供方便访问硬件的接口 二.不同领域的操作系统: 1 ...
- IdeaVim插件使用技巧--JetBrains Plugin Vim
在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件.在这里详细总结一下这个插件在日常编程中的一些常用小技巧.供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考.当然 ...
- python 装饰器 生成及原里
# 装饰器形成的过程 : 最简单的装饰器 有返回值的 有一个参数 万能参数 # 装饰器的作用 # 原则 :开放封闭原则 # 语法糖 :@ # 装饰器的固定模式 #不懂技术 import time # ...
- C++代码理解 (强制指针转换)
#include<iostream> using namespace std; class A { public: A() { a=; b=; c=; f=; } private: int ...
- Java重写构造方法
public class TestSuper { public static void main(String[] args) { new ChildClass("alex", 1 ...
- React16版本的新特性
React16版本更新的新特性 2018年05月03日 21:27:56 阅读数:188 1.render方法的返回值类型:New render return types 之前的方式: class A ...
- leetcode笔记--1 two-sum
my answer: 出现的问题:倒数第二行and i !=s这种情况没有考虑进去,以后要思考全面些