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)\)的简单路径(每个点最多经 ...
随机推荐
- wepy 编译警告去除办法
如果你用过wepy打包小程序的话,那么你一定碰到了很多坑,(什么也不用说,抱一下吧)下面记录的是本人遇到的一个小坑, 编译的时候出现了黄色警告 如果你出现了上图这样的话,相信你一定也知道什么意思,就是 ...
- Matlab学习笔记(二)
二.MATLAB基础知识 (二)数值.变量和表达式 命名规则: 变量名对大小写敏感,即区分大小写 变量名必须以字母开头,后面可以采用数字.下划线和字母,但不能使用空格.标点符号和运算符 变量名最长可以 ...
- Tomcat处理HTTP请求原理
一.Tomcat是什么? Tomcat是一个Web应用服务器,同时也是一个Servlet/JSP容器.Tomcat作为Servlet容器,负责处理客户端请求,把请求传送给Servlet,并将Servl ...
- hdu 1828 Picture(线段树,扫描线)
A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wa ...
- BZOJ 3754 Tree之最小方差树 MST
Description Wayne 在玩儿一个很有趣的游戏.在游戏中,Wayne 建造了N 个城市,现在他想在这些城市间修一些公路,当然并不是任意两个城市间都能修,为了道路系统的美观,一共只有M 对城 ...
- JS基础:正则表达式
简介 正则表达式 (regular expression) 描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子串.将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等.在 JS ...
- 2018/3/14 Hadoop学习笔记(一)
首先,什么是Hadoop?为什么它是现在大数据处理最热门的框架呢?(正确来说,现在Hadoop是一个生态圈) Hadoop是apache下一套开源的服务框架,它主要的作用就是利用服务器集群,来对海量数 ...
- HDU 4416 (后缀自动机)
HDU 4416 Good Article Good sentence Problem : 给一个串S,和一些串T,询问S中有多少个子串没有在T中出现. Solution :首先对所有的T串建立后缀自 ...
- CSS+Jquery实现QQ分组列表
实现效果图如下: 说明: 1.css隐藏分组下的好友内容: 2.Jquery实现点击分组项事件,实现好友内容的显示和隐藏: 3.样式1,可展开多个分组:样式2,只能有一个分组展开: 源码: <! ...
- tomcat会自动解压webapps目录下的war包
如图,把war包放到tomcat的webapps目录,会被自动解压