poj3471 - 倍增+LCA+树上差分
题意:一张n节点连通无向图,n-1条树边,m条非树边。若通过先删一条树边,再删一条非树边想操作
将此图划分为不连通的两部分,问有多少种方案。
利用LCA整好区间覆盖,dfs用来求前缀和
需要注意的是,覆盖数为1的时候才可以选择哦!
覆盖数为0,代表可以直接拆开
最后附上一张我老婆
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define maxn 110000
using namespace std;
typedef long long ll;
int dp[maxn][33];
int dep[maxn];
long long cnt[maxn];//差分数组
int head[450100]; struct Node {
int to;
int next;
}G[450100];
int cnn = 1;
void insert(int be, int en) {
G[cnn].to = en; G[cnn].next = head[be]; head[be] = cnn;;//头插法
cnn++;
} void dfs(int u, int par) {
dep[u] = dep[par] + 1;
for (int i = 0; i <= 21; i++) {
dp[u][i + 1] = dp[dp[u][i]][i];
}
for (int i = head[u]; i; i = G[i].next) {
int p = G[i].to;
if (p == par) continue;
dp[p][0] = u;
dfs(p, u);
}
return;
}
int LCA(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);//x在下面
for (int i = 20; i >= 0; i--) {
if (dep[dp[x][i]] >= dep[y]) x = dp[x][i];
if (x == y) return x;
} for (int i = 20; i >= 0; i--) {
if (dp[x][i] != dp[y][i]) {
x = dp[x][i];
y = dp[y][i]; }
} return dp[x][0];
}
int n, m;
int find(int x,int par) { for (int i = head[x]; i; i = G[i].next) {
int p = G[i].to;
if (p == par) continue;
find(p, x);
cnt[x] += cnt[p];
} return 0;
}
int main() {
scanf("%d %d", &n, &m);
int be, en;
for (int i = 0; i < n - 1; i++) {
scanf("%d %d", &be, &en);
insert(be, en);
insert(en, be);
}
dp[1][0] = 1;
dfs(1, 0);
for(int i=0;i<m;i++) {
scanf("%d %d", &be, &en);
int p = LCA(be, en);
cnt[p] -= 2;
cnt[be]++;
cnt[en]++;
}
find(1, 0);
ll ans = 0; for (int i = 2; i <= n; i++) {
if (cnt[i] == 0) ans += m;//乘法原理
else if (cnt[i] == 1) ans++;
}
printf("%lld\n", ans);
return 0;
}
poj3471 - 倍增+LCA+树上差分的更多相关文章
- 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)
[题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...
- [BZOJ3307]:雨天的尾巴(LCA+树上差分+权值线段树)
题目传送门 题目描述: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式: 第一 ...
- UVA1265 Tour Belt Kruskal重构树、倍增、树上差分
题目传送门 题意:定义$Tour \, Belt$为某张图上的一个满足以下条件的点集:①点集中至少有$2$个点②任意两点互相连通③图上两个端点都在这个点集中的边的权值的最小值严格大于图上只有一个端点在 ...
- [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)
题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- 洛谷P3258 [JLOI2014]松鼠的新家【LCA+树上差分】
简要题意 树上n个节点,给定路径,求每个点经过次数 题意分析 对于每两个点,有两种情况,第一种,他们的lca为本身,第二种,他们有公共祖先,又要求他们的点经过次数,暴力是不可能的,复杂度不对,所以可以 ...
- 运输计划[二分答案 LCA 树上差分]
也许更好的阅读体验 \(\mathcal{Description}\) 原题链接 概括一下题意 给一颗有\(n\)个点带边权的树,有\(m\)个询问,每次询问\(u,v\)两点间的权值和,你可以将树中 ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- bzoj4326 树链剖分 + 线段树 // 二分 lca + 树上差分
https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题意:N个点的树上给M条树链,问去掉一条边的权值之后所有树链长度和的最大值最小是多少. 首先 ...
- 2018.08.22 codves2370 小机房的树(lca+树上差分)
传送门 一道板子题. 直接树链剖分维护树上lca然后差分就行了. 代码: #include<bits/stdc++.h> #define N 50005 #define lc (p< ...
随机推荐
- spingboot项目在windows环境中运行时接收参数及日志中文乱码
1.logback.xml配置 appender中添加 <param name="Encoding" value="UTF-8" /> <co ...
- Myeclipse tomcat(jdk)安装
- 选用适合的ORACLE优化器
ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER ...
- @bzoj - 4709@ 柠檬
目录 @desription@ @solution@ @accepted code@ @details@ @desription@ 一共有 N 只贝壳,编号为 1...N,贝壳 i 的大小为 si. ...
- mysql统计信息相关
最近RDS FOR MYSQL5.6的统计信息有问题,一些表明明的数据,但统计信息里去显示为空表,导致执行计划出错,查询效率很低,所以查看下相关的信息. -- 查看服务器系统变量,实际上使用的变量的值 ...
- laravel 实现微博第三方登陆
https://blog.csdn.net/a12541254/article/details/79415550 1.安装 composer require socialiteproviders/we ...
- [C#] 如何把void*转换为byte[]
一般来说,C#库的对外接口应该提供byte[]这样比较容易用的接口,而不应该提供裸的void* 但是有些库确实是这么封装的.那么就有一个如何转换的问题.MSDN推荐的转换方式是使用UnmanagedM ...
- CODE FESTIVAL 2017 qual B C 3 Steps(补题)
总感觉这题是个题意杀,理解错题目了,看了好久才发现题目意思:操作是让,只要两点没有直接相连,而且只要有一条路的距离3,就可以把这两点连接起来. 按照题解中讲的,可以把图分为二分图和非二分图来解.不过题 ...
- jq on绑定事件off移除事件
https://www.cnblogs.com/sandraryan/ 以前用的是bind(); 后来更新后用的on (on() 方法是 bind().live() 和 delegate() 方法的新 ...
- 在linux上安装pear
在搭建centreon的过程中,需要pear模块支持. 什么是pear pear是PHP扩展与应用库(the PHP Extension and Application Repository)的缩写. ...