[APIO2018]铁人两项 --- 圆方树
[APIO2018] 铁人两项
题目大意:
给定一张图,问有多少三元组(a,b,c)(a,b,c 互不相等)满足存在一条点不重复的以a为起点,经过b,终点为c的路径
如果你不会圆方树 ----------------------- 放弃是最好的选择(先学了再来吧)
如果你会圆方树
考虑\((a,...,c)\)
1.如果a,c不同属一个点双,不难发现答案为路上经过的(点双的节点个数)的和减去割点数
2.如果a,c同属一个点双,那么答案为本点双的节点个数 - 2
自然地想到方点的权值为内含节点个数(割点算在内),圆点权值为 -1
所以答案就是树上的路径权值之和了。
树形DP一下就好了 ------------------------------------------- 那就是错了。。。。
考虑的三元组中的a,c明显指圆点,方点是不能作为路径的起点和终点的。。。。。
于是,考虑每个点能出现的路径个数。
记\(sz[e]\)表示节点e在圆方树的子树中存在多少圆点
对于每个点,存在两种路径:
分两种情况统计即可
额外的,对于圆点,因为可能作为起点,终点,还要额外统计
莫名其妙的$loj$和$luogu$的$rk1$.......还是挺懵逼的
代码如下:
#include <cstdio>
#define sid 500050
using namespace std; long long ans;
int n, m, top, tim, nt, cnt, Asz, pp;
int dfn[sid], low[sid], st[sid], sz[sid], val[sid];
int cap[sid], acap[sid], nxt[sid], node[sid]; int read() { scanf("%d", &pp); return pp; }
void upmin(int &a, int b) { if(a > b) a = b; }
void Add(int u, int v) { nxt[++ cnt] = cap[u]; cap[u] = cnt; node[cnt] = v; }
void Bdd(int u, int v) { nxt[++ cnt] = acap[u]; acap[u] = cnt; node[cnt] = v; } void Tarjan(int e) {
dfn[e] = low[e] = ++ tim;
st[++ top] = e; sz[e] = ; val[e] = -;
for(int i = acap[e], d; i; i = nxt[i])
if(!dfn[d = node[i]]) {
Tarjan(d); upmin(low[e], low[d]);
if(low[d] < dfn[e]) continue;
int p; ++ nt; Add(e, nt);
do {
p = st[top --]; val[nt] ++;
Add(nt, p); sz[nt] += sz[p];
} while(p != d);
val[nt] ++; sz[e] += sz[nt];
}
else upmin(low[e], dfn[d]);
} void DP(int e) {
if(e <= n) ans += 1ll * (Asz - ) * val[e];
ans += 1ll * (Asz - sz[e]) * sz[e] * val[e];
for(int i = cap[e]; i; i = nxt[i]) {
int d = node[i];
DP(d), ans += 1ll * (Asz - sz[d]) * sz[d] * val[e];
}
} int main() {
nt = n = read(); m = read();
for(int i = ; i <= m; i ++) {
int u = read(), v = read();
Bdd(u, v); Bdd(v, u);
}
for(int i = ; i <= n; i ++)
if(!dfn[i])
Tarjan(i), Asz = sz[i], DP(i);
printf("%lld\n", ans);
return ;
}
[APIO2018]铁人两项 --- 圆方树的更多相关文章
- [APIO2018]铁人两项——圆方树+树形DP
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...
- [APIO2018]铁人两项 [圆方树模板]
把这个图缩成圆方树,把方点的权值设成-1,圆点的权值设成点双的size,算 经过这个点的路径的数量*这个点的点权 的和即是答案. #include <iostream> #include ...
- [BZOJ5463][APIO2018]铁人两项(圆方树DP)
题意:给出一张图,求满足存在一条从u到v的长度大于3的简单路径的有序点对(u,v)个数. 做了上一题[HDU5739]Fantasia(点双连通分量+DP),这个题就是一个NOIP题了. 一开始考虑了 ...
- [APIO2018] Duathlon 铁人两项 圆方树,DP
[APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...
- 【Luogu4630】【APIO2018】 Duathlon 铁人两项 (圆方树)
Description 给你一张\(~n~\)个点\(~m~\)条边的无向图,求有多少个三元组\(~(x, ~y, ~z)~\)满足存在一条从\(~x~\)到\(~z~\)并且经过\(~y~\)的 ...
- LOJ 2587 「APIO2018」铁人两项——圆方树
题目:https://loj.ac/problem/2587 先写了 47 分暴力. 对于 n<=50 的部分, n3 枚举三个点,把图的圆方树建出来,合法条件是 c 是 s -> f 路 ...
- loj2587 「APIO2018」铁人两项[圆方树+树形DP]
主要卡在一个结论上..关于点双有一个常用结论,也经常作为在圆方树/简单路径上的良好性质,对于任意点双内互不相同的三点$s,c,t$,都存在简单路径$s\to c\to t$,证明不会.可以参见clz博 ...
- 洛谷P4630 铁人两项--圆方树
一道很好的圆方树入门题 感谢PinkRabbit巨佬的博客,讲的太好啦 首先是构建圆方树的代码,也比较好想好记 void tarjan(int u) { dfn[u] = low[u] = ++dfn ...
- [APIO2018]铁人两项(圆方树)
过了14个月再重新看这题,发现圆方树从来就没有写过.然后写了这题发现自己APIO2018打铁的原因竟然是没开long long,将树的部分的O(n)写挂了(爆int),毕竟去年APIO时我啥都不会,连 ...
随机推荐
- JAVA 企业培训
- 论文里有公式?用texlive+texstudio(windows下)
要写论文了,但论文里有一大堆公式,感觉很麻烦,经过询问同学知道有tex这么个东西,可以像写代码一样写论文,许多论文的格式都有相关的模板,所以学习一下,这里记录一下环境安装. texlive和texst ...
- MGR Switch Muti-Primary to single_primary
MGR Muti-Primary 切换 single_primary 模式 原因:因为希望做ProxySQL+MGR之间Proxy层的消耗测试,需要把原有的MGR多主改为单主模式. 修改MGRgrou ...
- 生成器(generator)和迭代(iterable , iterator, iteration)
在搞清楚Generator之前,我们先讨论一下 iterable , iterator, iteration 1.Iterable 我们知道,在Python中所有东西都是object, 比如说变量,容 ...
- MYSQL三种安装方式--二进制包安装
1. 把二进制包下载到/usr/local/src下 2. 如果是tar.gz包,则使用tar zxvf 进行解压 如果是tar包,则可以使用tar xvf 进行解压 3. $ mv mysql-5. ...
- PHP解决并发问题的几种实现
对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了 在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制. 方案一:使用文件锁排它锁 f ...
- C++中求类的大小
今天刷题时看到一题,是求类的大小的,其中涉及了内存的一些知识,记录一下. 正确答案是12和9 首先是内存对齐原则,可以参考这篇博文:http://www.cppblog.com/snailcong/a ...
- 【摘要】JavaScript 的性能优化:加载和执行
1.浏览器遇到js代码会暂停页面的下载和渲染,谁晓得js代码会不会把html给强奸(改变)了: 2.延迟脚本加载:defer 属性 <html> <head> <titl ...
- LightOJ - 1297 Largest Box LightOJ(一元三次方程求极大值)
题目链接:https://vjudge.net/contest/28079#problem/K 题目大意:给你一个长为L,宽为W的纸片,四个角剪掉边长为x的正方形,如下图所示,然后折成一个无盖的纸盒, ...
- Weex Workshop 挑战赛,等你来战!
一个颠覆性的移动开发方式,一个匠心打造的跨平台移动开发工具,一个后App时代的生产力解放者—Weex,针对App Native开发频繁发版和多端研发的痛点,H5开发的页面稳定性.性能体验等问题,提供了 ...