luogu 4630 [APIO2018] Duathlon 铁人两项
题目大意:
无向图上找三个点 a b c使存在一条从a到b经过c的路径
求取这三个点的方案数
思路:
建立圆方树
这个圆方树保证没有两个圆点相连或两个方点相连
对于每个节点x 设该节点为路径的中间节点
则a c要么同在一个子树内 要么一个在子树内另一个在子树外 最后对答案<<1
对于每个方点设val[x] 为该点所连圆点的个数
每个方点按照两种情况算出答案之后
用圆点减去算重的部分
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#define ll long long
#define inf 2139062143
#define MAXN 100100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,fst[MAXN],cnt,nxt[MAXN<<],to[MAXN<<];
int st[MAXN],top,dfn[MAXN],low[MAXN],stp,sz[MAXN<<],val[MAXN<<],sumsz;
ll ans=;
void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
vector<int>son[MAXN<<];
inline void tarjan(int x,int fa)
{
dfn[x]=low[x]=++stp,st[++top]=x;
sz[x]=,val[x]=-;int now=;
for(int i=fst[x];i;i=nxt[i])
if(!dfn[to[i]])
{
tarjan(to[i],x);low[x]=min(low[x],low[to[i]]);
if(low[to[i]]<dfn[x]) continue;val[++m]=;
do{now=st[top--],son[m].push_back(now),sz[m]+=sz[now],val[m]++;}
while(now!=to[i]);
son[x].push_back(m);sz[x]+=sz[m];
}
else low[x]=min(low[x],dfn[to[i]]);
}
void dfs(int x,int tot)
{
int tmp= x<=n;
for(int i=;i<son[x].size();i++)
{
dfs(son[x][i],tot);ans+=(ll)tmp*sz[son[x][i]]*val[x];tmp+=sz[son[x][i]];
}
ans+=(ll)sz[x]*(tot-sz[x])*val[x];
}
int main()
{
n=read(),m=read();int a,b;
while(m--){a=read(),b=read();add(a,b);add(b,a);}
m=n;
for(int i=;i<=n;i++)
if(!dfn[i]){tarjan(i,);dfs(i,sz[i]);}
printf("%lld\n",ans<<);
}
luogu 4630 [APIO2018] Duathlon 铁人两项的更多相关文章
- [APIO2018] Duathlon 铁人两项 圆方树,DP
[APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...
- [Luogu4630][APIO2018]Duathlon 铁人两项
luogu 题目描述 比特镇的路网由 \(m\) 条双向道路连接的 \(n\) 个交叉路口组成. 最近,比特镇获得了一场铁人两项锦标赛的主办权.这场比赛共有两段赛程:选手先完成一段长跑赛程,然后骑自行 ...
- P4630 [APIO2018] Duathlon 铁人两项
思路 圆方树,一个点双中的所有点都可以被经过,所以给圆点赋值-1,方点赋值为圆点个数,统计圆点两两之间的路径权值和即可 代码 #include <cstdio> #include < ...
- [APIO2018] Duathlon 铁人两项
不经过重点,考虑点双 点双,考虑圆方树 两个点s,t,中间路径上,所有点双里的点都可以经过,特别地,s,t作为割点的时候,不能往后走,也就是不能经过身后的方点 也就是,(s,t)经过树上路径上的所有圆 ...
- 【题解】APIO2018 Duathlon 铁人两项
首先对于给出的图建立圆方树,然后我们分类讨论每一个点作为中间的中转站出现的情况有多少种,累积到 \(ans\) 中. 对于圆点:在任意两个子树内分别选出一个节点都是合法的. 对于方点:连接向方点的点均 ...
- 洛谷P4630 [APIO2018] Duathlon 铁人两项 (圆方树)
圆方树大致理解:将每个点双看做一个新建的点(方点),该点双内的所有点(圆点)都向新建的点连边,最后形成一棵树,可以给点赋予点权,用以解决相关路径问题. 在本题中,方点点权赋值为该点双的大小,因为两个点 ...
- 洛谷P4630 [APIO2018] Duathlon 铁人两项 【圆方树】
题目链接 洛谷P4630 题解 看了一下部分分,觉得树的部分很可做,就相当于求一个点对路径长之和的东西,考虑一下能不能转化到一般图来? 一般图要转为树,就使用圆方树呗 思考一下发现,两点之间经过的点双 ...
- [洛谷P4630][APIO2018] Duathlon 铁人两项
题目大意:给一张无向图,求三元组$(u,v,w)$满足$u->v->w$为简单路径,求个数 题解:圆方树,缩点后$DP$,因为同一个点双中的点一定地位相同 卡点:1.$father$数组开 ...
- 【APIO2018】铁人两项
[APIO2018]铁人两项 题目描述 大意就是给定一张无向图,询问三元组\((s,c,f)\)中满足\(s\neq c\neq f\)且存在\((s\to c\to f)\)的简单路径(每个点最多经 ...
随机推荐
- win10 专业版 安装tornado 的步骤
win10 专业版 安装tornado 的步骤: 1.下载tornado源码压缩包 下载网址:https://github.com/tornadoweb/tornado 若是没有github 账号可以 ...
- ceph集群
ceph集群部署 ceph理解: Ceph是一个分布式存储,可以提供对象存储.块存储和文件存储,其中对象存储和块存储可以很好地和各大云平台集成.其他具体介绍可见官网简介:http://docs.cep ...
- 常用的四种设计模式 PHP代码
// 工厂模式 interface Iuser { public function getUserName(); } class UserFactory { static public functio ...
- Python数据结构--链表
class Node(): def __init__(self, dataval=None): self.dataval = dataval self.nextval = None class SLi ...
- Github ==〉本地(克隆)
[情景] 新员工入职后,一般会将项目下载到本地. [下载(克隆)] 命令 git clone url地址 示例
- HDU 1564 找规律博弈
题目大意是: 从n*n的方格角落的一个起点出发,每次移到上下左右一个未曾到达过的位置,谁不能走了谁就输了 想了好久都想不出,看了大神的题解 Orz了 果然博弈不是脑残的游戏啊... 这里从起点出发,将 ...
- cogs——73. 找最佳通路
73. 找最佳通路 ★☆ 输入文件:city.in 输出文件:city.out 简单对比时间限制:1 s 内存限制:128 MB 问题描述有 n 个 城市,它们之间的交通情况已知.现在 ...
- Win7 文件加密存储操作后,如何在事后备份证书、秘钥
这个密钥的特点是只有在此系统下用此账户才可以修改,即便是你用此账户设置加密后删除此账户再重新建一个同名的账户依然无法修改.而且此密钥无法破解.所以一旦加密后,重装系统或者更换账户就无法修改了.唯一的办 ...
- 采用jmeter测试dubbo服务接口
http://www.kissyu.org/2017/02/08/jmeter%E6%B5%8B%E8%AF%95dubbo%E6%8E%A5%E5%8F%A3/
- ViewFlipper实现ViewPager的页面切换效果
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...