2019.03.29 bzoj5463: [APIO2018] 铁人两项(圆方树+树形dp)
传送门
题意简述:给你一张无向图,问你满足存在从a−>b−>ca->b->ca−>b−>c且不经过重复节点的路径的有序点对(a,b,c)(a,b,c)(a,b,c)的数量。
思路:
对每一个连通块建一棵圆方树,然后可以按照圆点和方点做不同的树形dpdpdp。
圆点:找存在于两棵不同子树的点对数
方点:找存在于三颗不同子树的点对数。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
typedef long long ll;
const int N=2e5+5;
vector<int>e[N],g[N];
int n,m,low[N],all,dfn[N],sig,tot=0,stk[N],siz[N],top=0;
ll ans=0;
void tarjan(int p){
++all,low[p]=dfn[p]=++tot,stk[++top]=p;
for(ri i=0,v;i<e[p].size();++i){
if(!dfn[v=e[p][i]]){
tarjan(v),low[p]=min(low[v],low[p]);
if(low[v]>=dfn[p]){
g[++sig].push_back(p),g[p].push_back(sig);
int x;
do g[sig].push_back(x=stk[top--]),g[x].push_back(sig);while(x^v);
}
}
else low[p]=min(dfn[v],low[p]);
}
}
void dfs(int p,int fa){
siz[p]=p<=n;
int sum=0;
ll tmp=0;
for(ri i=0,v;i<g[p].size();++i)if((v=g[p][i])^fa){
dfs(v,p);
tmp+=(ll)sum*siz[v];
sum+=siz[v],siz[p]+=siz[v];
}
tmp+=(ll)sum*(all-siz[p]);
if(p<=n)ans+=tmp;
else{for(ri i=0,v;i<g[p].size();++i)if((v=g[p][i])^fa)ans+=tmp-(ll)(all-siz[v])*siz[v];ans+=tmp-(ll)(all-siz[p])*siz[p];}
}
int main(){
sig=n=read(),m=read();
for(ri i=1,u,v;i<=m;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
for(ri i=1;i<=n;++i)if(!dfn[i])all=0,tarjan(i),dfs(i,0);
cout<<ans*2;
return 0;
}
2019.03.29 bzoj5463: [APIO2018] 铁人两项(圆方树+树形dp)的更多相关文章
- [APIO2018]铁人两项——圆方树+树形DP
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...
- loj2587 「APIO2018」铁人两项[圆方树+树形DP]
主要卡在一个结论上..关于点双有一个常用结论,也经常作为在圆方树/简单路径上的良好性质,对于任意点双内互不相同的三点$s,c,t$,都存在简单路径$s\to c\to t$,证明不会.可以参见clz博 ...
- [BZOJ5463][APIO2018]铁人两项(圆方树DP)
题意:给出一张图,求满足存在一条从u到v的长度大于3的简单路径的有序点对(u,v)个数. 做了上一题[HDU5739]Fantasia(点双连通分量+DP),这个题就是一个NOIP题了. 一开始考虑了 ...
- [APIO2018] Duathlon 铁人两项 圆方树,DP
[APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...
- [APIO2018]铁人两项 --- 圆方树
[APIO2018] 铁人两项 题目大意: 给定一张图,问有多少三元组(a,b,c)(a,b,c 互不相等)满足存在一条点不重复的以a为起点,经过b,终点为c的路径 如果你不会圆方树 ------- ...
- [APIO2018]铁人两项 [圆方树模板]
把这个图缩成圆方树,把方点的权值设成-1,圆点的权值设成点双的size,算 经过这个点的路径的数量*这个点的点权 的和即是答案. #include <iostream> #include ...
- 【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 路 ...
- 洛谷P4630 铁人两项--圆方树
一道很好的圆方树入门题 感谢PinkRabbit巨佬的博客,讲的太好啦 首先是构建圆方树的代码,也比较好想好记 void tarjan(int u) { dfn[u] = low[u] = ++dfn ...
随机推荐
- 关于Qrc文件的用法
在python文件xxx.py中调用资源文件,一般来说,需要将资源放在xxx.py的相同目录下:然而,当在xxx.py下建立一个统一目录/rec则需要建立xxx.qrc文件才能让xxx.py调用,调用 ...
- spring注解-“@Scope”
@Scope可用来指定Spring创建bean的方式 默认为单实例,即@Scope("singleton").IOC容器启动的时候会调用方法创建对象并放到IOC容器中,以后每次获取 ...
- 移动web图片加载完获取img宽高
1.vue中 @load=function(){} 等待img加载完触发load函数 2.window.load=function(){var imgheight=$(".btnimg& ...
- 如果测试UI
1. 先分享几个链接 https://www.ranorex.com/resources/testing-wiki/gui-testing/ https://www.tutorialspoint.co ...
- 区间修改区间求和cdq分治
https://www.luogu.org/problemnew/show/P3372 #include<bits/stdc++.h> #define fi first #define s ...
- jupyter notebook 代码自动补齐插件
安装: . pip install jupyter_contrib_nbextensions -i https://pypi.mirrors.ustc.edu.cn/simple 2. jupyter ...
- gradle 排除jar包依赖
1.直接在configuration中排除 configurations { compile.exclude module: 'commons' all*.exclude group: 'org.gr ...
- mysql中查询的优先级
sql和mysql执行顺序,内部机制是一样的,最大的区别在别名上 一.sql执行顺序 1.from 2.on 3.join 4.where 5.group by(开始使用select中的别名,后面 的 ...
- heat-engine组件
1.heat-engine启动一个rpc server端,EngineService在初始化时加载heat.clients插件和初始化env, env中包括各种资源关键字对应的映射类和constrai ...
- python2与python3的区别
print 函数(Python3中print为一个函数,必须用括号括起来:Python2中print为class)在Python 2.6与Python 2.7里面,以下三种形式是等价的: print ...