【APIO2018】铁人两项
【APIO2018】铁人两项
大意就是给定一张无向图,询问三元组\((s,c,f)\)中满足\(s\neq c\neq f\)且存在\((s\to c\to f)\)的简单路径(每个点最多经过一次)的数量。
\(1\leq n,\leq 10^5,1\leq m\leq 2*10^5\)
我们考虑枚举\(s,f\)然后计算中间\(c\)的数量。我们发现对于一张图上统计两点之间路径上的点数量很好做。于是我们考虑建圆方树。
我们将圆点的权值定为\(-1\),将方点的权值定为与其直接相连的圆点的数量。\(u\)到\(v\)路径上可能经过的点的数量就是圆方树上\(u\to v\)路径上除了\(u,v\)的点权之和\(-2\)。
于是我们用树形\(\text{DP}\),计算每个点对答案的贡献。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 200005
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int n,m;
int tot;
struct graph {
int to[N<<2],nxt[N<<2];
int h[N],cnt;
void add(int i,int j) {
to[++cnt]=j;
nxt[cnt]=h[i];
h[i]=cnt;
}
}s,g;
int dfn[N],low[N],id;
int st[N];
int val[N];
void work(int v,int to) {
tot++;
g.add(v,tot);
val[tot]=1;
while(1) {
int j=st[st[0]--];
val[tot]++;
g.add(tot,j);
if(j==to) return ;
}
}
ll tot_size;
void tarjan(int v,int fr) {
tot_size++;
dfn[v]=low[v]=++id;
st[++st[0]]=v;
for(int i=s.h[v];i;i=s.nxt[i]) {
int to=s.to[i];
if(to==fr) continue ;
if(!dfn[to]) {
tarjan(to,v);
low[v]=min(low[v],low[to]);
if(low[to]>=dfn[v]) {
work(v,to);
}
} else low[v]=min(low[v],dfn[to]);
}
}
ll ans;
int size[N];
void dfs(int v) {
int tim=0;
for(int i=g.h[v];i;i=g.nxt[i]) {
int to=g.to[i];
dfs(to);
ans+=1ll*val[v]*size[v]*size[to];
tim+=size[v]*size[to];
size[v]+=size[to];
}
if(v<=n) size[v]++;
if(v<=n) {
tim+=(size[v]-1)*(tot_size-size[v]);
ans+=1ll*val[v]*(size[v]-1)*(tot_size-size[v]);
} else {
tim+=size[v]*(tot_size-size[v]);
ans+=1ll*val[v]*size[v]*(tot_size-size[v]);
}
}
int main() {
n=Get(),m=Get();
tot=n;
int a,b;
for(int i=1;i<=m;i++) {
a=Get(),b=Get();
s.add(a,b),s.add(b,a);
}
for(int i=1;i<=n;i++) val[i]=-1;
for(int i=1;i<=n;i++) {
if(dfn[i]) continue ;
tot_size=0;
tarjan(i,0);
dfs(i);
ans-=1ll*tot_size*(tot_size-1);
}
cout<<ans*2;
return 0;
}
【APIO2018】铁人两项的更多相关文章
- [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时我啥都不会,连 ...
- 2019.03.29 bzoj5463: [APIO2018] 铁人两项(圆方树+树形dp)
传送门 题意简述:给你一张无向图,问你满足存在从a−>b−>ca->b->ca−>b−>c且不经过重复节点的路径的有序点对(a,b,c)(a,b,c)(a,b,c) ...
- LOJ.2587.[APIO2018]铁人两项Duathlon(圆方树)
题目链接 LOJ 洛谷P4630 先对这张图建圆方树. 对于S->T这条(些)路径,其对答案的贡献为可能经过的所有点数,那么我们把方点权值设为联通分量的大小,可以直接去求树上路径权值和. 因为两 ...
- [BZOJ5463][APIO2018]铁人两项:Tarjan+圆方树
分析 根据题目中的要求,从\(s\)出发前往\(f\)一定可以,并且只可能经过这两个结点所在的点双连通分量和它们之间的点双连通分量,因此切换点\(c\)只能从这些点中选取. 建出圆方树后,因为圆方树上 ...
- 洛谷P4630 [APIO2018]铁人两项 [广义圆方树]
传送门 又学会了一个新东西好开心呢~ 思路 显然,假如枚举了起始点\(x\)和终止点\(y\),中转点就必须在它们之间的简单路径上. 不知为何想到了圆方树,可以发现,如果把方点的权值记为双联通分量的大 ...
- [BZOJ5463] [APIO2018] 铁人两项
题目链接 LOJ. BZOJ. Solution 先建圆方树. 我们考虑暴力,枚举一个点对,我们枚举的点都是圆点,然后统计中间那个点可以取的位置的数量,加起来就是答案. 那么怎么统计呢,我们对于每个点 ...
- LOJ2587:[APIO2018]铁人两项——题解
https://loj.ac/problem/2587#submit_code (题面来自LOJ) 考试时候发觉树很可做,并且写了一个dp骗到了树的分. 苦于不会圆方树……现在回来发现这题还是很可做的 ...
随机推荐
- 从零开始学安全(十五)●DHCP服务
DHCP,全名为:Dynamic Host Configuration Protocol,动态主机配置协议,它是一种基于UDP的局域网协议,其作用主要有:给主机自动分配IP地址,管理员通过该协议管理内 ...
- BurpSuite 各模块使用
Proxy 代理 对浏览器进行代理 对浏览器增加代理服务器 可以对http 请求进行监视 intercept is on 进行监控 off 不监控 可以任意修改 对任意的网络请求 进行爬虫 在 s ...
- If you did this already, delete the swap file ".git/.MERGE_MSG.swp"
出现这种情况一般是不正常退出造成的,找到隐藏文件后删除解决
- 小tips:JS之break,continue和return这三个语句的用法
break语句 break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句.由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的break语句才是 ...
- vuejs2.0使用Sortable.js实现的拖拽功能
简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jquery ui中的sortable.js,只是在拖拽完成后,在update的回调函数中又重新排序了存放数据的数组.但 ...
- 中文代码示例之Electron桌面应用开发初体验
参考: 打造你的第一个 Electron 应用 首先运行下面在目录下创建package.json: $ npm init 去掉了一些无关项后内容如下: { "name": &quo ...
- filter帅选
var ages = [32, 33, 16, 40]; ages= ages.filter(function checkAdult(obj) {//obj表示数组中的每个元素 return obj ...
- spring boot 基础 2018年5月3日
主包下运行类@SpringBootApplication 此注解是核心注解,源码如下 @Target({ElementType.TYPE}) @Retention(RetentionPolicy.R ...
- git 入门教程之知识速查
知识速查 创建版本库 初始化项目 git init 从零开始创建项目 示例 git init 克隆项目 git clone 将已有项目拷贝到本地 示例 git clone git@github.com ...
- (python)数据结构---元组
一.描述 一个有序的元素组成的集合 元组是不可变的线性数据结构 二.元组的相关操作 1.元组元素的访问 索引不可超界,否则抛异常IndexError 支持正负索引 t = (2, 3) print(t ...