[BZOJ5463] [APIO2018] 铁人两项
题目链接
LOJ.
BZOJ.
Solution
先建圆方树。
我们考虑暴力,枚举一个点对,我们枚举的点都是圆点,然后统计中间那个点可以取的位置的数量,加起来就是答案。
那么怎么统计呢,我们对于每个点赋一个点权,方点点权为点双的大小,圆点点权为\(-1\)。
那么这条路径的点权和就是答案,注意要统计到端点的权值。
然后优化就很显然了,直接枚举每个点被算了多少次就行了,这个随便算一下就好了。
复杂度\(O(n)\)。
#include<bits/stdc++.h>
using namespace std;
#define int long long
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
#define lf double
#define ll long long
const int maxn = 4e5+10;
const int inf = 1e9;
const lf eps = 1e-8;
int cnt,n,m,val[maxn],ans,rt;
struct Tree {
int head[maxn],tot,vis[maxn],sz[maxn];
struct edge{int to,nxt;}e[maxn<<1];
void add(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;}
void ins(int u,int v) {add(u,v),add(v,u);}
void dfs(int x,int fa) {
vis[x]=1,sz[x]=x<=n;
for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa) dfs(e[i].to,x),sz[x]+=sz[e[i].to];
}
void solve(int x,int fa) {
int res=0,s=0;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa) res+=s*sz[e[i].to],s+=sz[e[i].to];
res+=s*(sz[rt]-sz[x]);res<<=1;ans+=res*val[x];
for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa) solve(e[i].to,x);
}
}T;
struct Graph {
int head[maxn],tot,dfn[maxn],low[maxn],dfn_cnt,sta[maxn],top;
struct edge{int to,nxt;}e[maxn<<1];
void add(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;}
void ins(int u,int v) {add(u,v),add(v,u);}
void tarjan(int x,int fa) {
dfn[x]=low[x]=++dfn_cnt,sta[++top]=x;
for(int v,i=head[x];i;i=e[i].nxt) {
if((v=e[i].to)==fa) continue;
if(!dfn[v]) tarjan(v,x),low[x]=min(low[x],low[v]);
else {low[x]=min(low[x],dfn[v]);continue;}
if(low[v]>=dfn[x]) {
++cnt;T.ins(cnt,x);val[cnt]++;
while(top) {
int now=sta[top--];T.ins(now,cnt),val[cnt]++;
if(now==v) break;
}
}
}
}
}G;
signed main() {
read(n),read(m);for(int i=1,x,y;i<=m;i++) read(x),read(y),G.ins(x,y);
cnt=n;for(int i=1;i<=n;i++) if(!G.dfn[i]) G.tarjan(i,0);
for(int i=1;i<=n;i++) val[i]=-1;
for(int i=1;i<=n;i++) if(!T.vis[i]) rt=i,T.dfs(i,0),T.solve(i,0),ans-=T.sz[i]*(T.sz[i]-1)*2;
write(ans);
return 0;
}
[BZOJ5463] [APIO2018] 铁人两项的更多相关文章
- 2019.03.29 bzoj5463: [APIO2018] 铁人两项(圆方树+树形dp)
传送门 题意简述:给你一张无向图,问你满足存在从a−>b−>ca->b->ca−>b−>c且不经过重复节点的路径的有序点对(a,b,c)(a,b,c)(a,b,c) ...
- [BZOJ5463][APIO2018]铁人两项:Tarjan+圆方树
分析 根据题目中的要求,从\(s\)出发前往\(f\)一定可以,并且只可能经过这两个结点所在的点双连通分量和它们之间的点双连通分量,因此切换点\(c\)只能从这些点中选取. 建出圆方树后,因为圆方树上 ...
- [BZOJ5463][APIO2018]铁人两项(圆方树DP)
题意:给出一张图,求满足存在一条从u到v的长度大于3的简单路径的有序点对(u,v)个数. 做了上一题[HDU5739]Fantasia(点双连通分量+DP),这个题就是一个NOIP题了. 一开始考虑了 ...
- [APIO2018]铁人两项 --- 圆方树
[APIO2018] 铁人两项 题目大意: 给定一张图,问有多少三元组(a,b,c)(a,b,c 互不相等)满足存在一条点不重复的以a为起点,经过b,终点为c的路径 如果你不会圆方树 ------- ...
- [APIO2018]铁人两项——圆方树+树形DP
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...
- [APIO2018]铁人两项 [圆方树模板]
把这个图缩成圆方树,把方点的权值设成-1,圆点的权值设成点双的size,算 经过这个点的路径的数量*这个点的点权 的和即是答案. #include <iostream> #include ...
- [APIO2018]铁人两项(圆方树)
过了14个月再重新看这题,发现圆方树从来就没有写过.然后写了这题发现自己APIO2018打铁的原因竟然是没开long long,将树的部分的O(n)写挂了(爆int),毕竟去年APIO时我啥都不会,连 ...
- LOJ.2587.[APIO2018]铁人两项Duathlon(圆方树)
题目链接 LOJ 洛谷P4630 先对这张图建圆方树. 对于S->T这条(些)路径,其对答案的贡献为可能经过的所有点数,那么我们把方点权值设为联通分量的大小,可以直接去求树上路径权值和. 因为两 ...
- 洛谷P4630 [APIO2018]铁人两项 [广义圆方树]
传送门 又学会了一个新东西好开心呢~ 思路 显然,假如枚举了起始点\(x\)和终止点\(y\),中转点就必须在它们之间的简单路径上. 不知为何想到了圆方树,可以发现,如果把方点的权值记为双联通分量的大 ...
随机推荐
- 水灾 1000MS 64MB (广搜)
水灾(sliker.cpp/c/pas) 1000MS 64MB 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY ...
- c++ reference can not be reassigned
#include <iostream> using namespace std; int main () { // declare simple variables int i; int ...
- PS 去皱纹
1.打开一个有皱纹的图片,选择修复画笔工具,按住Alt键吸取一块光滑的皮肤,然后再在有皱纹的位置上点击即可
- 「专题训练」k-Tree(CodeForces Round #247 Div.2 C)
题意与分析(Codeforces-431C) 题意是这样的:给出K-Tree--一个无限增长的树,它的每个结点都恰有\(K\)个孩子,每个节点到它\(K\)个孩子的\(K\)条边的权重各为\(1,2, ...
- Qt-QML-Loader初步接触
先说说为什么用到了QML的Loader,这里我就要先扯点别的,那就是QML自带的ColorDialog,QML的机制 是优先调用系统提供的ColorDialog,如果系统的ColorDialog的不可 ...
- Qt PC 安卓 tcp传输文件
废话不多说,如题,上代码 qt PC端 头文件 //网络部分 #include <QTcpSocket> #include <QFile> #include <QFile ...
- php常用几个数组的区别
本文主要介绍的php数组函数主要有:sort.rsort.asort.arsort.ksort.krsort 测试数据定义一个关联数组如下: $data=[ 'f'=>123, 'b'=> ...
- JEMTER简单的测试计划
测试计划一 1)测试网站:http://www.geneedu.cn/和http://supu01.1688.com/ 2)测试目的是该网站在负载达到20 QPS 时的响应时间. 备注: QPS : ...
- 【progress】 进度条组件说明
progress 进度条组件 原型: <progress percent="[Float(0-100)]" show-info="[Boolean]" b ...
- 孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境
孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境 (完整学习过程屏幕记录视频地址在文末) 学习Python我肯定不会错过图片文字的识别,当然更重要的是简单的验证码识别了,今天 ...