LCA题集
点的距离(模板题)
树中两点间的距离就是d[u] + d[v] - 2 * d[lca(u, v)]
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e5 + 10;
const int MAXM = 20;
struct Edge { int to, next; };
Edge e[MAXN << 1];
int head[MAXN], num, n;
int up[MAXN][MAXM + 10], d[MAXN];
void AddEdge(int from, int to)
{
e[num] = Edge{to, head[from]};
head[from] = num++;
}
void dfs(int u, int fa)
{
for(int i = head[u]; ~i; i = e[i].next)
{
int v = e[i].to;
if(v == fa) continue;
d[v] = d[u] + 1;
up[v][0] = u;
dfs(v, u);
}
}
void get_up()
{
_for(j, 1, MAXM)
_for(i, 1, n)
up[i][j] = up[up[i][j-1]][j-1];
}
int lca(int u, int v)
{
if(d[u] < d[v]) swap(u, v);
for(int i = MAXM; i >= 0; i--)
if(d[up[u][i]] >= d[v])
u = up[u][i];
if(u == v) return u;
for(int i = MAXM; i >= 0; i--)
if(up[u][i] != up[v][i])
u = up[u][i], v = up[v][i];
return up[u][0];
}
int main()
{
memset(head, -1, sizeof(head));
num = 0; scanf("%d", &n);
REP(i, 1, n)
{
int u, v;
scanf("%d%d", &u, &v);
AddEdge(u, v); AddEdge(v, u);
}
dfs(1, -1);
get_up();
int q; scanf("%d", &q);
while(q--)
{
int u, v;
scanf("%d%d", &u, &v);
printf("%d\n", d[u] + d[v] - 2 * d[lca(u, v)]);
}
return 0;
}
暗的连锁
这道题首先有个转化
切两刀能不能切断,取决于非树边,因为非树边会构成环
那么可以把非树边构成的环上所有的树边都覆盖一次
如果只覆盖一次,那么显然有唯一解
如果没有被覆盖,那就加上非树边的数目,因为第二刀可以切任意一条非树边
如果覆盖两次以上,那么两刀是不能解决问题的。
所以就有维护每条边被覆盖了多少次
这里用到了树上差分,f[u]表示u与u的父亲连的边的覆盖次数
对于非树边u, v,让f[u]++, f[v]++, f[lca(u, v)]--
最后在“前缀和回来”,即统计所有子树的值加起来,就是答案
最后注意计算答案的时候根的f数组不算,因为根没有父亲
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e5 + 10;
const int MAXM = 20;
struct Edge{ int to, next; };
Edge e[MAXN << 1];
int head[MAXN], num, n, m;
int up[MAXN][MAXM + 10], d[MAXN];
int f[MAXN];
void read(int& x)
{
int f = 1; x = 0; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
x *= f;
}
void AddEdge(int to, int from)
{
e[num] = Edge{to, head[from]};
head[from] = num++;
}
void dfs(int u, int fa)
{
for(int i = head[u]; ~i; i = e[i].next)
{
int v = e[i].to;
if(v == fa) continue;
d[v] = d[u] + 1;
up[v][0] = u;
dfs(v, u);
}
}
int dp(int u, int fa)
{
for(int i = head[u]; ~i; i = e[i].next)
{
int v = e[i].to;
if(v == fa) continue;
dp(v, u);
f[u] += f[v];
}
}
void init()
{
dfs(1, -1);
_for(j, 1, MAXM)
_for(i, 1, n)
up[i][j] = up[up[i][j - 1]][j - 1];
}
int lca(int u, int v)
{
if(d[u] < d[v]) swap(u, v);
for(int i = MAXM; i >= 0; i--)
if(d[up[u][i]] >= d[v])
u = up[u][i];
if(u == v) return u;
for(int i = MAXM; i >= 0; i--)
if(up[u][i] != up[v][i])
u = up[u][i], v = up[v][i];
return up[u][0];
}
int main()
{
read(n);read(m);
memset(head, -1, sizeof(head)); num = 0;
REP(i, 1, n)
{
int u, v; read(u), read(v);
AddEdge(u, v); AddEdge(v, u);
}
init();
_for(i, 1, m)
{
int u, v; read(u), read(v);
f[u]++; f[v]++; f[lca(u, v)] -= 2;
}
dp(1, -1);
int ans = 0;
_for(i, 2, n)
{
if(f[i] == 1) ans++;
if(f[i] == 0) ans += m;
}
printf("%d\n", ans);
return 0;
}
LCA题集的更多相关文章
- 【转】Tarjan&LCA题集
转自:http://blog.csdn.net/shahdza/article/details/7779356 [HDU][强连通]:1269 迷宫城堡 判断是否是一个强连通★2767Proving ...
- ACM题集以及各种总结大全!
ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...
- ACM题集以及各种总结大全(转)
ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...
- 全国各大 oj 分类题集...
各种题集从易到难刷到手软 你准备好了吗? 准备剁手吧
- 组合数取模&&Lucas定理题集
题集链接: https://cn.vjudge.net/contest/231988 解题之前请先了解组合数取模和Lucas定理 A : FZU-2020 输出组合数C(n, m) mod p (1 ...
- Bug是一种财富-------研发同学的错题集、测试同学的遗漏用例集
此文已由作者王晓明授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 各位看官,可能看到标题的你一定认为这是一篇涉嫌"炒作"的文章,亦或是为了吸引眼球而起的标 ...
- 数位dp题集
题集见大佬博客 不要62 入门题,检验刚才自己有没有看懂 注意一些细节. 的确挺套路的 #include<bits/stdc++.h> #define REP(i, a, b) for(r ...
- 二级C语言题集
时间:2015-5-13 18:01 在131题之后是按考点分类的题集,有需要的朋友可以看一下 ---------------------------------------------------- ...
- LCA入门题集小结
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目: How far away ? Time Limit: 2000/1000 MS (Jav ...
随机推荐
- Centos6下创建Centos6基础镜像
在centos6下可以使用官方仓库拉取一个指定系统类型跟tag的镜像到本地 [root@localhost ~]# docker pull centos:6.8 6.8: Pulling from c ...
- 【Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) C】
[链接] 我是链接,点我呀:) [题意] 给你一个字符串s. 让你在其中的某一些位置进行操作.. 把[1..i]和[i+1..n]翻转. 使得里面01交替出现的那种子串的长度最长. [题解] 可以用a ...
- 关于excel导入、导出(POI)
当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际的开发中, ...
- 多校第二场 1004 hdu 5303 Delicious Apples(背包+贪心)
题目链接: 点击打开链接 题目大意: 在一个周长为L的环上.给出n棵苹果树.苹果树的位置是xi,苹果树是ai,苹果商店在0位置,人的篮子最大容量为k,问最少做多远的距离可以把苹果都运到店里 题目分析: ...
- Quartz2D二维画图引擎
Quartz2D二维画图引擎 这个二维画图引擎的功能很强大 一般苹果公司xcode 提供给我们的一些UI控件不能满足我们的需求 所以我们会自己定义控件 xcode 提供的全部控件都是由这个画图引擎画出 ...
- This Activity already has an action bar supplied by the window decor
问题描写叙述:继承自AppCompatActivity,使用Toolbar替代ActionBar的时候.出现错误 错误信息: 2.Caused by: java.lang.IllegalStateEx ...
- webview同步cookies
目前很多android app都内置了可以显示web页面的界面,会发现这个界面一般都是由一个叫做WebView的组件渲染出来的,学习该组件可以为你的app开发提升扩展性. 先说下WebView的一些优 ...
- 风暴英雄 http 302重定向 正在等待游戏模式下载完成
抓包 在抓到的数据包里面,看到一个http get请求,右键选中,然后follow stream wireshark自动进行数据包过滤tcp.stream eq 1340,并且可以看到完整的数据通讯 ...
- php实现邮箱激活功能
php实现邮箱激活功能 一.样例 二.文件结构 其中swiftmailer-master是第三方插件,用来发验证邮件 三.核心代码 doAction.php 响应页面 <?php header( ...
- NumPy和Pandas常用库
NumPy和Pandas常用库 1.NumPy NumPy是高性能科学计算和数据分析的基础包.部分功能如下: ndarray, 具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组. 用于对整组数 ...