[洛谷P4630][APIO2018] Duathlon 铁人两项
题目大意:给一张无向图,求三元组$(u,v,w)$满足$u->v->w$为简单路径,求个数
题解:圆方树,缩点后$DP$,因为同一个点双中的点一定地位相同
卡点:1.$father$数组开小,一不小心就续到了下面的$bool$的$vis$数组中,然后就挂成$98$,因为发现去掉没用的$vis$数组变成$86$,才找到问题
C++ Code:
#include <cstdio>
#include <cstring>
#define maxn 100010
#define maxm 200010
#define N 200010 #define ONLINE_JUDGE
#define read() R::READ()
#include <cctype>
namespace R {
int x;
#ifdef ONLINE_JUDGE
char *ch, op[1 << 28];
inline void init() {
fread(ch = op, 1, 1 << 28, stdin);
}
inline int READ() {
while (isspace(*ch)) ch++;
for (x = *ch & 15, ch++; isdigit(*ch); ch++) x = x * 10 + (*ch & 15);
return x;
}
#else
char ch;
inline int READ() {
ch = getchar();
while (isspace(ch)) ch = getchar();
for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
return x;
}
#endif
} int n, m;
long long ans;
inline int min(int a, int b) {return a < b ? a : b;} namespace Tree {
int CNT;
int head[N], cnt;
struct Edge {
int to, nxt;
} e[N << 1];
void add(int a, int b) {
e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
e[++cnt] = (Edge) {a, head[b]}; head[b] = cnt;
} long long w[N], f[N], sz[N], pointsz;
int fa[N];
void dfs(int u) {
sz[u] = bool(u <= n);
long long tmp = 0;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa[u]) {
fa[v] = u;
dfs(v);
tmp += sz[v] * sz[u];
sz[u] += sz[v];
}
}
tmp += sz[u] * (pointsz - sz[u]);
ans += w[u] * tmp << 1ll;
}
}
namespace Graph {
int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxm << 1];
void add(int a, int b) {
e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
e[++cnt] = (Edge) {a, head[b]}; head[b] = cnt;
} int DFN[maxn], low[maxn], idx, fa[maxn];
int S[maxn], top;
void Tarjan(int u) {
Tree::pointsz++;
DFN[u] = low[u] = ++idx;
Tree::w[S[++top] = u] = -1;
int v;
for (int i = head[u]; i; i = e[i].nxt) {
v = e[i].to;
if (!DFN[v]) {
fa[v] = u;
Tarjan(v);
low[u] = min(low[u], low[v]);
if (low[v] >= DFN[u]) {
Tree::w[++Tree::CNT] = 1;
Tree::add(Tree::CNT, u);
do {
v = S[top--];
Tree::add(Tree::CNT, v);
Tree::w[Tree::CNT]++;
} while (v != e[i].to);
}
} else low[u] = min(low[u], DFN[v]);
}
}
inline void tarjan(int n) {
for (int i = 1; i <= n; i++) if (!DFN[i]) {
Tree::pointsz = 0;
Tarjan(i);
Tree::dfs(i);
}
}
} int main() {
#ifdef ONLINE_JUDGE
R::init();
#endif
Tree::CNT = n = read(), m = read();
for (int i = 1; i <= m; i++) Graph::add(read(), read());
Graph::tarjan(n);
printf("%lld\n", ans);
return 0;
}
[洛谷P4630][APIO2018] Duathlon 铁人两项的更多相关文章
- 洛谷P4630 [APIO2018] Duathlon 铁人两项 【圆方树】
题目链接 洛谷P4630 题解 看了一下部分分,觉得树的部分很可做,就相当于求一个点对路径长之和的东西,考虑一下能不能转化到一般图来? 一般图要转为树,就使用圆方树呗 思考一下发现,两点之间经过的点双 ...
- 洛谷P4630 [APIO2018] Duathlon 铁人两项 (圆方树)
圆方树大致理解:将每个点双看做一个新建的点(方点),该点双内的所有点(圆点)都向新建的点连边,最后形成一棵树,可以给点赋予点权,用以解决相关路径问题. 在本题中,方点点权赋值为该点双的大小,因为两个点 ...
- P4630 [APIO2018] Duathlon 铁人两项
思路 圆方树,一个点双中的所有点都可以被经过,所以给圆点赋值-1,方点赋值为圆点个数,统计圆点两两之间的路径权值和即可 代码 #include <cstdio> #include < ...
- [APIO2018] Duathlon 铁人两项 圆方树,DP
[APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...
- [Luogu4630][APIO2018]Duathlon 铁人两项
luogu 题目描述 比特镇的路网由 \(m\) 条双向道路连接的 \(n\) 个交叉路口组成. 最近,比特镇获得了一场铁人两项锦标赛的主办权.这场比赛共有两段赛程:选手先完成一段长跑赛程,然后骑自行 ...
- [APIO2018] Duathlon 铁人两项
不经过重点,考虑点双 点双,考虑圆方树 两个点s,t,中间路径上,所有点双里的点都可以经过,特别地,s,t作为割点的时候,不能往后走,也就是不能经过身后的方点 也就是,(s,t)经过树上路径上的所有圆 ...
- 【题解】APIO2018 Duathlon 铁人两项
首先对于给出的图建立圆方树,然后我们分类讨论每一个点作为中间的中转站出现的情况有多少种,累积到 \(ans\) 中. 对于圆点:在任意两个子树内分别选出一个节点都是合法的. 对于方点:连接向方点的点均 ...
- luogu 4630 [APIO2018] Duathlon 铁人两项
题目大意: 无向图上找三个点 a b c使存在一条从a到b经过c的路径 求取这三个点的方案数 思路: 建立圆方树 这个圆方树保证没有两个圆点相连或两个方点相连 对于每个节点x 设该节点为路径的中间节点 ...
- 【APIO2018】铁人两项(圆方树,动态规划)
[APIO2018]铁人两项(圆方树,动态规划) 题面 UOJ 洛谷 BZOJ 题解 嘤嘤嘤,APIO的时候把一个组合数写成阶乘了,然后这题的70多分没拿到 首先一棵树是很容易做的,随意指定起点终点就 ...
随机推荐
- 写给iOS小白的MVVM教程(序)
这几天,需要重构下部分代码,这里简要记录下.但是涉及的技术要点还是很多,所以分为多个篇章叙述.此教程来源于,并将于应用于实践,不做过多的概念性阐释和争论.每个篇章都会附上实际的可执行的代码.因涉及的技 ...
- springboot整合activiti报错[processes/]不存在解决方案
springboot整合activiti时,启动抛异常 nested exception is java.io.FileNotFoundException: class path resource [ ...
- 关于discuz 不能全文搜索的问题
这个问题客服反馈很多次了,以为discuz 默认搜索只能搜标题,除非配置了sphinx全文搜索引擎. 但是之前比较老的员工说以前能用的,也就是discuz老版本. 今天突然想到是不是discuz纵横搜 ...
- mybatis中oracle转mysql
刚来公司实习,遇到的第一个任务就是这个,简单记录一下思路过程.人菜的很,没啥参考价值. 测试时: 将现有的oracle库转为mysql: 用的Navicat自带数据传输功能,简单粗暴 出现的问题: 1 ...
- <Docker学习>5. docker数据管理
当我们创建了一个tomcat容器,如何简单部署一个web应用?如何将war包放入到容器中?也就是说怎么样把文件从宿主机中 "放入" 到容器中? docker cp命令可以将宿主机本 ...
- <Docker学习>4. docker容器的使用
简单的说, 容器是独立运行的一个或一组应用, 以及它们的运行态环境. 对应的, 虚拟机可以理解为模拟运行的一整套操作系统( 提供了运行态环境和其他系统环境) 和跑在上面的应用.容器的运行是基于镜像的. ...
- LINUX操作系统知识:进程与线程详解
当一个程序开始执行后,在开始执行到执行完毕退出这段时间内,它在内存中的部分就叫称作一个进程. Linux 是一个多任务的操作系统,也就是说,在同一时间内,可以有多个进程同时执行.我们大家常用的单CPU ...
- [CodeForces - 296D]Greg and Graph(floyd)
Description 题意:给定一个有向图,一共有N个点,给邻接矩阵.依次去掉N个节点,每一次去掉一个节点的同时,将其直接与当前节点相连的边和当前节点连出的边都需要去除,输出N个数,表示去掉当前节点 ...
- Android面试收集录9 IntentService详解
一. 定义 IntentService是Android里面的一个封装类,继承自四大组件之一的Service. 二.作用 处理异步请求,实现多线程 三. 工作流程 注意:若启动IntentService ...
- 15.8,redis-cluster配置
为什么要用redis-cluster 1.并发问题 redis官方生成可以达到 10万/每秒,每秒执行10万条命令假如业务需要每秒100万的命令执行呢? 2.数据量太大 一台服务器内存正常是16~ ...