【刷题】LOJ 2587 「APIO2018」铁人两项
题目描述
比特镇的路网由 \(m\) 条双向道路连接的 \(n\) 个交叉路口组成。
最近,比特镇获得了一场铁人两项锦标赛的主办权。这场比赛共有两段赛程:选手先完成一段长跑赛程,然后骑自行车完成第二段赛程。
比赛的路线要按照如下方法规划:
1、先选择三个两两互不相同的路口 \(s\) ,\(c\) 和 \(f\) ,分别作为比赛的起点、切换点(运动员在长跑到达这个点后,骑自行车前往终点)、终点。
2、选择一条从 \(s\) 出发,经过 \(c\) 最终到达 \(f\) 的路径。考虑到安全因素,选择的路径经过同一个点至多一次。
在规划路径之前,镇长想请你帮忙计算,总共有多少种不同的选取 \(s\) ,\(c\) 和 \(f\) 的方案,使得在第 2 步中至少能设计出一条满足要求的路径。
输入格式
第一行包含两个整数 \(n\) 和 \(m\) ,分别表示交叉路口和双向道路的数量。
接下来 \(m\) 行,每行两个整数 \(v_i\) ,\(u_i\) 。表示存在一条双向道路连接交叉路口 \(v_i\) , \(u_i\) (\(1 \le v_i, u_i \le n, v_i \neq u_i\))。
保证任意两个交叉路口之间,至多被一条双向道路直接连接。
输出格式
输出一行,包括一个整数,表示能满足要求的不同的选取 \(s\) , \(c\) 和 \(f\) 的方案数。
样例
样例输入1
4 3
1 2
2 3
3 4
样例输出1
8
样例解释1
在第一个样例中,有以下 8 种不同的选择 \((s, c, f)\) 的方案:\((1, 2, 3)\),\((1, 2, 4)\),\((1, 3, 4)\),\((2, 3, 4)\),\((3, 2, 1)\),\((4, 2, 1)\),\((4, 3, 1)\),\((4, 3, 2)\) 。
样例输入2
4 4
1 2
2 3
3 4
4 2
样例输出2
14
样例解释2
在第二个样例中,有以下 14 种不同的选择 \((s, c, f)\) 的方案:\((1, 2, 3)\),\((1, 2, 4)\),\((1, 3, 4)\),\((1, 4, 3)\),\((2, 3, 4)\),\((2, 4, 3)\),\((3, 2, 1)\),\((3, 2, 4)\),\((3, 4, 1)\),\((3, 4, 2)\),\((4, 2, 1)\),\((4, 2, 3)\),\((4, 3, 1)\),\((4, 3, 2)\) 。
数据范围与提示
子任务 1(5 分):\(n \le 10 , m \le 100\)
子任务 2(11 分):\(n \le 50 , m \le 100\)
子任务 3(8 分):\(n \le 100\,000\) ,每个交叉路口至多作为两条双向道路的端点。
子任务 4(10 分):\(n \le 1\,000\) ,在路网中不存在环。
存在环是指存在一个长度为 \(k\) (\(k\ge 3\)) 的交叉路口序列 \(v_1, v_2, \ldots v_k\) ,序列中的路口编号两两不同,且对于 \(i\) 从 \(1\) 到 \(k-1\) ,有一条双向道路直接连接路口 \(v_i\) 和 \(v_{i+1}\) ,且有一条双向道路直接连接路口 \(v_k\) 和 \(v_1\) 。
子任务 5(13 分):\(n \le 100\,000\) ,在路网中不存在环。
子任务 6(15 分):\(n \le 1\,000\) ,对于每个交叉路口,至多被一个环包含。
子任务 7(20 分):\(n \le 100\,000\) ,对于每个交叉路口,至多被一个环包含。
子任务 8(8 分):\(n \le 1\,000, m \le 2\,000\)
子任务 9(10 分):\(n \le 100\,000, m \le 200\,000\)
题解
考场上就多写了个树的,后来发现圆方树的做法好简单啊,居然没想出来qwq
求出点双并且建出圆方树后,假设确定了 \(s\) 和 \(f\) ,那么 \(c\) 的情况就是 \(s\) 到 \(f\) 的路径上的点相邻的不同的圆点的个数
令每个方点的权值等于其度数,圆点的权值等于 \(-1\) ,那么 \(c\) 的数量就等于 \(s\) 到 \(f\) 路径上的权值和
所以就可以一个树形dp,线性统计答案了
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10,MAXM=200000+10;
int n,m,e,to[MAXM<<2],nex[MAXM<<2],out[MAXM<<2],beg[MAXN<<1],val[MAXN<<1],Visit_Num,DFN[MAXN],LOW[MAXN],cnt,Be[MAXN],size[MAXN<<1],vis[MAXN<<1],bel[MAXN<<1],all[MAXN<<1],clk;
ll ans;
std::stack<int> s;
std::vector<int> point[MAXN];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y)
{
to[++e]=y;
nex[e]=beg[x];
out[e]=x;
beg[x]=e;
}
inline void Tarjan(int x,int f)
{
DFN[x]=LOW[x]=++Visit_Num;bel[x]=clk;all[clk]++;
for(register int i=beg[x];i;i=nex[i])
if(to[i]==f)continue;
else if(!DFN[to[i]])
{
s.push(i);
Tarjan(to[i],x);
chkmin(LOW[x],LOW[to[i]]);
if(LOW[to[i]]>=DFN[x])
{
int temp;++cnt;
do{
temp=s.top();
s.pop();
if(Be[out[temp]]!=cnt)
{
Be[out[temp]]=cnt;
point[cnt].push_back(out[temp]);
}
if(Be[to[temp]]!=cnt)
{
Be[to[temp]]=cnt;
point[cnt].push_back(to[temp]);
}
}while(out[temp]!=x||to[temp]!=to[i]);
}
}
else if(DFN[to[i]]<DFN[x])s.push(i),chkmin(LOW[x],DFN[to[i]]);
}
inline void dfs(int x,int f)
{
vis[x]=1;
for(register int i=beg[x];i;i=nex[i])
if(to[i]==f)continue;
else
{
dfs(to[i],x);
ans+=1ll*val[x]*size[x]*size[to[i]];
size[x]+=size[to[i]];
}
if(x<=n)size[x]++;
if(x<=n)ans+=1ll*val[x]*(size[x]-1)*(all[bel[x]]-size[x])-all[bel[x]]+1;
else ans+=1ll*val[x]*size[x]*(all[bel[x]]-size[x]);
}
int main()
{
read(n);read(m);
for(register int i=1;i<=m;++i)
{
int u,v;read(u);read(v);
insert(u,v);insert(v,u);
}
for(register int i=1;i<=n;++i)
if(!DFN[i])clk++,Tarjan(i,0);
e=0;memset(beg,0,sizeof(beg));
for(register int i=1;i<=n;++i)val[i]=-1;
for(register int i=1;i<=cnt;++i)
for(register int j=0,lt=point[i].size();j<lt;++j)
{
bel[i+n]=bel[point[i][j]];
insert(i+n,point[i][j]);
insert(point[i][j],i+n);
val[i+n]++;
}
for(register int i=1;i<=n;++i)
if(!vis[i])dfs(i,0);
write(ans<<1,'\n');
return 0;
}
【刷题】LOJ 2587 「APIO2018」铁人两项的更多相关文章
- LOJ #2587「APIO2018」铁人两项
是不是$ vector$存图非常慢啊...... 题意:求数对$(x,y,z)$的数量使得存在一条$x$到$z$的路径上经过$y$,要求$x,y,z$两两不同 LOJ #2587 $ Solutio ...
- LOJ 2587 「APIO2018」铁人两项——圆方树
题目:https://loj.ac/problem/2587 先写了 47 分暴力. 对于 n<=50 的部分, n3 枚举三个点,把图的圆方树建出来,合法条件是 c 是 s -> f 路 ...
- 【LOJ】#2587. 「APIO2018」铁人两项
题解 学习了圆方树!(其实是复习了Tarjan求点双) 我又双叒叕忘记了tarjan点双一个最重要,最重要的事情! 就是--假如low[v] >= dfn[u],我们就找到了一个点双,开始建立方 ...
- loj2587 「APIO2018」铁人两项[圆方树+树形DP]
主要卡在一个结论上..关于点双有一个常用结论,也经常作为在圆方树/简单路径上的良好性质,对于任意点双内互不相同的三点$s,c,t$,都存在简单路径$s\to c\to t$,证明不会.可以参见clz博 ...
- loj2587 「APIO2018」铁人两项
圆方树orz,参见猫的课件(apio和wc的)以及这里那里 #include <iostream> #include <cstdio> using namespace std; ...
- 【APIO2018】铁人两项(圆方树,动态规划)
[APIO2018]铁人两项(圆方树,动态规划) 题面 UOJ 洛谷 BZOJ 题解 嘤嘤嘤,APIO的时候把一个组合数写成阶乘了,然后这题的70多分没拿到 首先一棵树是很容易做的,随意指定起点终点就 ...
- [APIO2018] Duathlon 铁人两项 圆方树,DP
[APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...
- 【APIO2018】铁人两项
[APIO2018]铁人两项 题目描述 大意就是给定一张无向图,询问三元组\((s,c,f)\)中满足\(s\neq c\neq f\)且存在\((s\to c\to f)\)的简单路径(每个点最多经 ...
- LOJ #2585. 「APIO2018」新家
#2585. 「APIO2018」新家 https://loj.ac/problem/2585 分析: 线段树+二分. 首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左 ...
随机推荐
- tomcat-在eclipse中配置tomcat容器的内存
eclipse下的tomcat内存设置大小 在eclipse中设置: 设置步骤如下: 1.点击eclipse上的debug图标旁边的下拉箭头 2.然后选择Run Configurations, 3.系 ...
- 20155308《网络对抗》Exp9 Web安全基础实践
20155308<网络对抗>Exp9 Web安全基础实践 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 基础问题回答 SQL注入攻击原理,如何防御? 原理:攻 ...
- 《网路对抗》Exp8 WEB基础实践
20155336<网路对抗>Exp8 WEB基础实践 一.基础问题回答 1.什么是表单 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等 ...
- VS编程,WPF中,获取鼠标相对于当前屏幕坐标的一种方法
原文:VS编程,WPF中,获取鼠标相对于当前屏幕坐标的一种方法 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/det ...
- Luogu P1484 种树
这道题目还是比较简单的 首先题目的意思就让我们很轻易地想到DP 我们设f[i][j]表示前i个坑中种j棵树的最大利益,则有: f[i][j]=max(f[i-1][j],f[i-2][j-1]+a[i ...
- Yii2中的format
关于format,这个也非常方便, 用来格式化内容的. 如下代码: <?= DetailView::widget([ 'model' => $model, 'attributes' =&g ...
- cocos2d-x学习记录5——CCTransition场景过渡
利用CCTransition能够创建出一系列的场景过渡动画,能够使场景切换时更加绚丽丰富. CCTransition派生出很多过渡动画,传入的参数一般包括过渡时间和创建的场景. MyScene.h内容 ...
- SSISDB5:使用TSQL脚本执行Package
SSISDB 系列随笔汇总: SSISDB1:使用SSISDB管理Package SSISDB2:SSIS工程的操作实例 SSISDB3:Package的执行实例 SSISDB4:当前正在运行的Pac ...
- java批量爬取电影资源
摘要 网上有很多个人站来分享电影资源,其实有时候我们自己也想做这个一个电影站来分享资源.但是这个时候就有一个问题,电影的资源应该从哪里来呢?难道要自己一条条手动去从网络上获取,这样无疑是缓慢而又效率低 ...
- 基于约束的SQL攻击
前言 值得庆幸的是如今开发者在构建网站时,已经开始注重安全问题了.绝大部分开发者都意识到SQL注入漏洞的存在,在本文我想与读者共同去探讨另一种与SQL数据库相关的漏洞,其危害与SQL注入不相上下,但却 ...