【APIO 2018】铁人两项(圆方树)
题意大概是,求有多少三元组$(s,c,f)(s \neq c, c \neq f, s \neq f)$,满足从$s$到$f$有一条简单路径经过$c$。
得到结论:
- 点双中任意互不相同的三个点,必定存在一条简单路径依次经过这三个点。
- 显然,割点只能经过一次。
建出一棵圆方树,圆点的权值为$-1$,方点的权值为该点双中点的个数,那任意两个圆点之间可以作为它们中转点的个数就是它们在圆方树上路径的点权和。
具体来讲就是割点上只能经过一次,圆点设成$-1$是为了去重方便。
以前只写过点双缩树,这里写圆方树更方便,权且将这道题作为学习的例题吧。
建圆方树只要在Tarjan上稍作修改,这里给出建树的例子:
void Tarjan(int x, int fa) {
sta[++top] = x; in[x] = -;
dfn[x] = low[x] = ++_clock;
for (int i = las[x]; i; i = pre[i]) {
if (to[i] == fa) continue;
if (dfn[to[i]]) {
low[x] = std::min(low[x], dfn[to[i]]);
} else {
Tarjan(to[i], x);
low[x] = std::min(low[x], low[to[i]]);
if (dfn[x] <= low[to[i]]) {
xtr[x].push_back(++c_n); ++in[c_n];
for (int t = -; t != to[i]; ) {
t = sta[top--];
xtr[c_n].push_back(t); ++in[c_n];
}
}
}
}
}
(注:xtr为圆方树,in < 0代表圆点,否则代表了该方点中点双里点的个数)
之后这个题就好做了,统计的是所有圆点点对间路径长度的总和。
#include <cstdio>
#include <vector>
#include <iostream> typedef long long LL;
const int N = ; int n, m;
int dfn[N], low[N], in[N], siz[N], sta[N], top, _clock, c_n;
std::vector<int> xtr[N];
LL ans, sum[N]; int yun = , las[N], to[N << ], pre[N << ];
inline void Add(int a, int b) {
to[++yun] = b; pre[yun] = las[a]; las[a] = yun;
} void Tarjan(int x, int fa) {
sta[++top] = x; in[x] = -;
dfn[x] = low[x] = ++_clock;
for (int i = las[x]; i; i = pre[i]) {
if (to[i] == fa) continue;
if (dfn[to[i]]) {
low[x] = std::min(low[x], dfn[to[i]]);
} else {
Tarjan(to[i], x);
low[x] = std::min(low[x], low[to[i]]);
if (dfn[x] <= low[to[i]]) {
xtr[x].push_back(++c_n); ++in[c_n];
for (int t = -; t != to[i]; ) {
t = sta[top--];
xtr[c_n].push_back(t); ++in[c_n];
}
}
}
}
} void Dfs(int x) {
if (in[x] < ) siz[x] = , sum[x] = in[x];
for (int i = ; i < (int)xtr[x].size(); ++i) {
int v = xtr[x][i];
Dfs(v);
siz[x] += siz[v];
sum[x] += (LL) siz[v] * in[x] + sum[v];
}
}
void Calc(int x) {
if (in[x] < ) ans += sum[x] - in[x];
LL cnt = ;
for (int i = ; i < (int)xtr[x].size(); ++i) {
int v = xtr[x][i];
ans += (LL) sum[v] * (siz[x] - (in[x] < ) - siz[v]);
cnt += (LL) siz[v] * (siz[x] - (in[x] < ) - siz[v]);
}
ans += (LL) cnt / * in[x];
for (int i = ; i < (int)xtr[x].size(); ++i) {
int v = xtr[x][i];
Calc(v);
}
} int main() {
scanf("%d%d", &n, &m);
c_n = n;
for (int i = , x, y; i <= m; ++i) {
scanf("%d%d", &x, &y);
Add(x, y); Add(y, x);
}
for (int i = ; i <= n; ++i) {
if (!dfn[i]) {
Tarjan(i, );
Dfs(i);
Calc(i);
}
}
printf("%lld\n", ans * ); return ;
}
$\bigodot$技巧&套路:
- 圆方树的构建,圆方树上的统计技巧,可以用圆点的权值设成$-1$来去重。
【APIO 2018】铁人两项(圆方树)的更多相关文章
- [APIO2018] Duathlon 铁人两项 圆方树,DP
[APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...
- [APIO2018]铁人两项 --- 圆方树
[APIO2018] 铁人两项 题目大意: 给定一张图,问有多少三元组(a,b,c)(a,b,c 互不相等)满足存在一条点不重复的以a为起点,经过b,终点为c的路径 如果你不会圆方树 ------- ...
- [APIO2018]铁人两项 [圆方树模板]
把这个图缩成圆方树,把方点的权值设成-1,圆点的权值设成点双的size,算 经过这个点的路径的数量*这个点的点权 的和即是答案. #include <iostream> #include ...
- [APIO2018]铁人两项——圆方树+树形DP
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...
- 洛谷P4630 铁人两项--圆方树
一道很好的圆方树入门题 感谢PinkRabbit巨佬的博客,讲的太好啦 首先是构建圆方树的代码,也比较好想好记 void tarjan(int u) { dfn[u] = low[u] = ++dfn ...
- 【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博 ...
- [BZOJ5463][APIO2018]铁人两项(圆方树DP)
题意:给出一张图,求满足存在一条从u到v的长度大于3的简单路径的有序点对(u,v)个数. 做了上一题[HDU5739]Fantasia(点双连通分量+DP),这个题就是一个NOIP题了. 一开始考虑了 ...
- 解题:APIO 2018 铁人两项
题面 建立圆方树,考虑所有路径,发现路径上原来的点双(现在的方点)里的点都可以做中间点.但是路径上被方点夹着的圆点被计重了,要扣掉:枚举的两个端点也被算进去了,要扣掉.所以直接将方点权值设为点双大小, ...
随机推荐
- 32bit 天堂2 windows 2003 server架设教程
安装环境::[注意:本教程newauth要用不加密的版本] windows 2003 enterprise server 100用户license Microsoft sql server 2000 ...
- 数学建模及机器学习算法(一):聚类-kmeans(Python及MATLAB实现,包括k值选取与聚类效果评估)
一.聚类的概念 聚类分析是在数据中发现数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好.我们事先并不知道数据的正确结果(类标),通过聚类算法来发现和挖掘数据本身的结 ...
- 【Python3.6】python打包成exe
D:\python_test>pip3 install pyinstaller…………D:\python_test>pyinstaller -F -w ui.py INFO: PyInst ...
- FinTech领域实践:乐维监控助力西南某上市城商行IT运维转型升级!
FinTech领域实践:乐维监控助力西南某上市城商行IT运维转型升级! 项目背景 随着信息化的逐步深入,企业业务运营活动对IT的依赖程度越来越高,传统的局部.粗放.碎片化的IT运维管理模式已经无法满足 ...
- Codeforces1151E,F | 553Div2 | 瞎讲报告
传送链接 E. Number of Components 当时思博了..一直在想对于\([1,r]\)的联通块和\([1,l-1]\)的联通块推到\([l,r]\)的联通块...我真的是傻了..这题明 ...
- IDEA下载插件超时的原因
setting中红框的对勾去掉就可以下载插件了
- Daily Scrum4 11.6
昨天的任务按时完成了,但是通过不到两周的时间,我们的工作依旧停留在修改上届学长代码中.今天上课和老师提出了这样的问题,助教在TFS上重新加载了10级学长的代码. 从上届学长代码那里我们发现,他们没有实 ...
- 【Alpha】阶段第七次Scrum Meeting
[Alpha]阶段第七次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 增加上课信息接口 编写按学院搜索课程接口 赵智源 构建后测试点测试框架 构建前测试点测试 ...
- Hive问题
今天一直遇到一个问题: 在查询最热10个关键词时候总是报错,下图为报错最下面 一直关注着failed的内容,头疼了一天......... 结果实验室老哥给指出问题,是yarnException报错, ...
- 浅谈对IT的认识!
我是一个从农村出来的学生,家里的情况和大多数的农村同学是一样的,家里算不上有钱,父母供我读书,也已经是做到仁至义尽了. 我现在选了,一个和计算机有关的专业---计算机应用技术.就是希望毕业后,可以找到 ...