点的距离(模板题)

树中两点间的距离就是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题集的更多相关文章

  1. 【转】Tarjan&LCA题集

    转自:http://blog.csdn.net/shahdza/article/details/7779356 [HDU][强连通]:1269 迷宫城堡 判断是否是一个强连通★2767Proving ...

  2. ACM题集以及各种总结大全!

    ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...

  3. ACM题集以及各种总结大全(转)

    ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...

  4. 全国各大 oj 分类题集...

    各种题集从易到难刷到手软  你准备好了吗? 准备剁手吧

  5. 组合数取模&&Lucas定理题集

    题集链接: https://cn.vjudge.net/contest/231988 解题之前请先了解组合数取模和Lucas定理 A : FZU-2020  输出组合数C(n, m) mod p (1 ...

  6. Bug是一种财富-------研发同学的错题集、测试同学的遗漏用例集

    此文已由作者王晓明授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 各位看官,可能看到标题的你一定认为这是一篇涉嫌"炒作"的文章,亦或是为了吸引眼球而起的标 ...

  7. 数位dp题集

    题集见大佬博客 不要62 入门题,检验刚才自己有没有看懂 注意一些细节. 的确挺套路的 #include<bits/stdc++.h> #define REP(i, a, b) for(r ...

  8. 二级C语言题集

    时间:2015-5-13 18:01 在131题之后是按考点分类的题集,有需要的朋友可以看一下 ---------------------------------------------------- ...

  9. LCA入门题集小结

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目: How far away ? Time Limit: 2000/1000 MS (Jav ...

随机推荐

  1. django-6-数据库配置及模型创建,激活(django模型系统1)

    <<<数据库的连接配置>>> django配置mysql的流程: 1.创建数据库用户 (1)进入MySQL数据库    (2)创建有数据库权限的用户 (3)退出My ...

  2. Hibernate 一对多

    表与表之间关系回顾(重点) 1 一对多 (1)分类和商品关系,一个分类里面有多个商品,一个商品只能属于一个分类 (2)客户和联系人是一对多关系 - 客户:与公司有业务往来,百度.新浪.360 - 联系 ...

  3. Guava工具类

    原文链接:http://blog.csdn.net/mnmlist/article/details/53425865 Objects类 Objects类有几个比较不错的方法,toString.hash ...

  4. 利用反射api查找一个类的具体信息

    讲到这个实例,首先介绍下本人,我是一个php程序猿.从事drupal开发2年多.能够说从实习開始就接触这个,至今没有换过.drupal给我的感觉是俩字"强大",今天写一个views ...

  5. XML系统学习

    参考:W3School XML基本概念 1.XML是eXtensible Markup Language,使用DTD(Document Type Definition)来描述数据,主要是为传输和存储数 ...

  6. spring Batch实现数据库大数据量读写

    spring Batch实现数据库大数据量读写 博客分类: spring springBatchquartz定时调度批处理  1. data-source-context.xml <?xml v ...

  7. 初识cocos2dx——入门第一篇

    享受"啪"的按下Enter的快感. (by云风) cocos2dx是不是个toy引擎,不同的人有不同的看法.可是你不得不承认它非常受欢迎.好多非常火的手游使用的就是cocos2dx ...

  8. Java学习之道:Java 导出EXCEL

    1.Apache POI简单介绍  Apache POI是Apache软件基金会的开放源代码函式库.POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开 ...

  9. 7.gcc的使用

    什么是gcc gcc编译器(GNU C Compiler) 现在我们所说的 gcc 是 GUN Compiler Collection的缩写,可以支持多种语言编译,比如 C,C++,Java, pas ...

  10. 本地PC安裝Centos 6.5 操作手冊

    http://www.xlgps.com/article/130038.html 一.准备工作 1.下载Centos6.5 ISO文件 我在官网上下的6.5版本CentOS-6.5-x86_64-bi ...