题目链接:【http://acm.hdu.edu.cn/showproblem.php?pid=6203】
题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点。
题解 :求每个点对的LCA,然后根据LCA的深度排序。从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1。
#include<Bits/stdc++.h> using namespace std; const int maxn = 2e5 + 5; int N, Q; int c[maxn], In[maxn], Out[maxn], cnt; struct Edge { int id, next; Edge(int id = 0, int next = 0): id(id), next(next) {} } E[maxn << 1]; //双向边 int head[maxn], tot; void initEdge() { memset(c, 0, sizeof(c)); cnt = 0; for(int i = 0; i <= N; i++) head[i] = -1; tot = 0; } void addEdge(int u, int v) { E[tot] = Edge(v, head[u]); head[u] = tot++; } int siz[maxn], top[maxn], dep[maxn], fa[maxn]; int clk;//需要初始化 void DFS1(int u, int p) { In[u] = ++cnt; dep[u] = dep[p] + 1; fa[u] = p, siz[u] = 1; for(int k = head[u]; k != -1; k = E[k].next) { int id = E[k].id; if(id == p) continue; DFS1(id, u); siz[u] += siz[id]; } Out[u] = cnt; } void DFS2(int u, int p) { int son = -1; for(int k = head[u]; k != -1; k = E[k].next)//找重儿子 { int id = E[k].id; if(id == p)continue; if(son == -1 || siz[id] > siz[son]) son = id; } if(son != -1) { top[son] = top[u]; DFS2(son, u); } for(int k = head[u]; k != -1; k = E[k].next) { int id = E[k].id; if(id == p || id == son)continue; top[id] = id; DFS2(id, u); } } int LCA(int x, int y) { while(top[x] != top[y]) { if(dep[top[x]] < dep[top[y]]) swap(x, y); x = fa[top[x]]; } if(dep[x] > dep[y]) swap(x, y); return x; } struct node { int u, v, lca; bool operator < (const node &T) const { return dep[lca] > dep[T.lca]; } } qry[50050]; int low_Bit(int x) { return x & -x; } void update(int x, int val) { while(x <= N) { c[x] += val; x += low_Bit(x); } } int get_sum(int x) { int ret = 0; while(x > 0) { ret += c[x]; x -= low_Bit(x); } return ret; } int main() { while(~scanf("%d", &N)) { N++; initEdge(); for(int i = 1; i <= N - 1; i++) { int u, v; scanf("%d %d", &u, &v); u++, v++; addEdge(u, v), addEdge(v, u); } DFS1(1, 0),top[1] = 1,DFS2(1, 0); scanf("%d", &Q); for(int i = 1; i <= Q; i++) { scanf("%d %d", &qry[i].u, &qry[i].v); qry[i].u++, qry[i].v++; qry[i].lca = LCA(qry[i].u, qry[i].v); } sort(qry + 1, qry + 1 + Q); int ans = 0; for(int i = 1; i <= Q; i++) { int u = qry[i].lca; int ret = get_sum(In[qry[i].u]) + get_sum(In[qry[i].v]); if(ret) continue; ans++; update(In[u], 1); update(Out[u] + 1, -1); } printf("%d\n", ans); } return 0; }
时间: 2024-09-30 21:29:47