当前位置:网站首页>【模板】【luogu P4630】Duathlon 铁人两项(圆方树)
【模板】【luogu P4630】Duathlon 铁人两项(圆方树)
2022-07-04 15:18:00 【SSL_TJH】
Duathlon 铁人两项
题目链接:luogu P4630
题目大意
给你一个无向图,然后你可以按顺序选三个点 a,b,c,保证 a 可以到 b,b 可以到 c,而且存在方案使得这两个路径的交点只有 b。
然后问你有多少个满足的三元组。
思路
首先如果这个是森林的话那我们可以很好的搞。
(反正各种方法随便你)
那我们现在是一个图,那就不好搞了。
那我们考虑能不能把它变成树?于是就可以用圆方树了。
圆方树
在讲圆方树之前,让我们先给出一些定义:
点双连通图
如果是有向图,就有一个强连通图。那无向图就会有一个点双连通图和一个边双连通图。
边双连通子图这里没用到就不说了,我们给出点双连通的子图的定义:图中任意两不同点之间都有至少两条点不重复的路径。
(因为一个点的比较不好搞所以我们默认没有孤立点,如果题目中有就按照题目要求特殊处理)
然后你会发现有一个近似等价的定义是不存在割点的图。
发现反例只有两个点一条边的情况(或者你也可以认为不是反例,因为你起点终点一定要重复的)
点双连通分量
跟强连通分量一样,就是一个图的极大点双连通子图。
但是你如果画个图你不难发现就是一个点是可能在若干个点双中的,但是一个边只会在一个中。
圆方树
那在圆方树中,我们把原来的点看做原点,每个点双对应一个方点。
(不难看出方点数量最多为 n n n,所以记得总共要开 2 n 2n 2n)
然后一个方点向它点双里面的点(原点)连边。
然后这个图就变成了若干格菊花,每个菊花通过原图的割点连接起来。
然后你不难想象任意一套树上路径都是圆方点交错的。
建
考虑用类似 Tarjan 的方法。
那因为无向图,所以我们找到新点的时候更新 l o w low low 是跟 l o w low low 更新,找到原来的点的时候就要跟 d f n dfn dfn 更新。
那你会发现也是找环的顶端,那条件就是 d f n u = l o w x dfn_u=low_x dfnu=lowx(然后 u u u 就是最顶端)
然后你就可以建出来了。
这道题
那如果是树上的很好搞,我们考虑把环通过圆方树弄成树,然后看看方点那边要怎么处理。
然后我们其实会发现你一个点双里面任意两个点之间,对于其他的每个点都有一种方法可以走过。
(小小证明就是你可以把这个点双拉成一个环,然后就没啦)
然后你就发现如果你要经过一个方点,你里面的点都可以经过,那我们可以把方点的权值赋做它点双的大小,然后路径上的方点的权值和就是固定了 s , f s,f s,f 满足条件的 c c c 的个数。
然后你发现你算重了,因为相邻的两个方点之间是通过点连接起来的,所以每个点其实都会充当一个连接的位置,所以我们要把点的权值弄成 − 1 -1 −1。
然后这里是要求所有的,我们就小小树形 DP 一下,考虑每个点对所有包含他的路径的贡献即可。
(子树内部,子树和外面)
代码
#include<cstdio>
#include<vector>
#include<iostream>
#define ll long long
using namespace std;
const int N = 1e5 + 100;
int n, m;
vector <int> G[N];
struct YF_tree {
int dfn[N], low[N], sta[N], tot, deg[N << 1], fa[N << 1][21];
int val[N << 1], num, sz[N << 1];
vector <int> GG[N << 1];
ll ans;
void link(int x, int y) {
GG[x].push_back(y); GG[y].push_back(x);
}
void tarjan(int now) {
dfn[now] = low[now] = ++dfn[0]; sta[++sta[0]] = now; num++;
for (int i = 0; i < G[now].size(); i++) {
int x = G[now][i];
if (!dfn[x]) {
tarjan(x); low[now] = min(low[now], low[x]);
if (dfn[now] == low[x]) {
tot++;
while (sta[sta[0]] != x) {
link(sta[sta[0]], tot);
sta[0]--; val[tot]++;
}
link(sta[sta[0]], tot); sta[0]--; val[tot]++;
link(now, tot); val[tot]++;
}
}
else low[now] = min(low[now], dfn[x]);
}
}
void dfs(int now, int father) {
if (now <= n) sz[now] = 1;
for (int i = 0; i < GG[now].size(); i++) {
int x = GG[now][i];
if (x != father) {
dfs(x, now);
ans += 2ll * sz[now] * sz[x] * val[now];
sz[now] += sz[x];
}
}
ans += 2ll * sz[now] * (num - sz[now]) * val[now];
}
void Init() {
tot = n; for (int i = 1; i <= n; i++) val[i] = -1;
for (int i = 1; i <= n; i++) if (!dfn[i]) num = 0, tarjan(i), dfs(i, 0);
}
}T;
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int x, y; scanf("%d %d", &x, &y);
G[x].push_back(y); G[y].push_back(x);
}
T.Init();
printf("%lld", T.ans);
return 0;
}
边栏推荐
- Research Report on surgical otorhinolaryngology equipment industry - market status analysis and development prospect prediction
- Li Kou today's question -1200 Minimum absolute difference
- go-micro教程 — 第二章 go-micro v3 使用Gin、Etcd
- Task state rollback and data blocking tasks based on check point mechanism
- How to implicitly pass values when transferring forms
- Research Report of exoskeleton robot industry - market status analysis and development prospect prediction
- Array filter fliter in JS
- Sequence diagram data modeling and industrial chain analysis
- Research Report on market supply and demand and strategy of China's plastics and polymer industry
- Learn more about the basic situation of 2022pmp examination
猜你喜欢

昆明三环闭合工程将经过这些地方,有在你家附近的吗?

C# 服务器日志模块

51 single chip microcomputer temperature alarm based on WiFi control

《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(2)-初识Fiddler让你理性认识一下

Go development: how to use go singleton mode to ensure the security of high concurrency of streaming media?

多年锤炼,迈向Kata 3.0 !走进开箱即用的安全容器体验之旅| 龙蜥技术

Understand ThreadLocal in one picture

新的职业已经出现,怎么能够停滞不前 ,人社部公布建筑新职业

基于wifi控制的51单片机温度报警器

一图看懂ThreadLocal
随机推荐
tp配置多数据库
Overflow: the combination of auto and Felx
话里话外:流程图绘制初级:六大常见错误
Software Engineer vs Hardware Engineer
Solution du système de gestion de la chaîne d'approvisionnement du parc logistique intelligent
Accounting regulations and professional ethics [8]
APOC自定义函数和过程
js中的数组筛选fliter
APOC custom functions and procedures
"Cannot initialize Photoshop because the temporary storage disk is full" graphic solution
Accounting regulations and professional ethics [7]
Is it safe to open an account online
中位数与次序统计量
Accounting regulations and professional ethics [6]
如何为ONgDB核心项目源码做贡献
Redis: SDS source code analysis
Go language loop statement (under Lesson 10)
电子元器件B2B商城系统开发:赋能企业构建进销存标准化流程实例
线性时间排序
GO开发:如何利用Go单例模式保障流媒体高并发的安全性?