UOJ#416. 【APIO2018】铁人两项
原文链接www.cnblogs.com/zhouzhendong/p/UOJ416.html
前言
完了完了SB选手Tarjan写挂。
题解
考虑先Tarjan缩个点双建个圆方树。
然后发现,确定起点和终点后,中间点的可选方案数就是 这条路径上的所有点双 size 之和-2 。
定义原点表示原图中的点,方点表示圆方树中新加入的点。
这个东西可以转化为路径上的方点度数之和减去原点个数。
定义点 x 的权值 d[x] ,当 x 为圆点时 d[x] = -1,否则 d[x] 等于 x 的度数。
设起点终点都是圆点的经过点 x 的路径条数为 c[x],那么点 x 对答案的贡献就是 d[x] * c[x] 。
时间复杂度 $O(n)$。
代码
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define real __zzd001
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
#define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\
For(_v2,L,R)printf("%d ",a[_v2]);puts("");
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> vi;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=100005*2;
int n,m,k;
vector <int> e[N],t[N];
LL ans=0;
int dfn[N],low[N],st[N],Time=0,top=0;
void Add_Edge(int x,int y){
t[x].pb(y),t[y].pb(x);
}
int Size;
void Tarjan(int x){
Size++;
dfn[x]=low[x]=++Time;
st[++top]=x;
for (auto y : e[x])
if (!dfn[y]){
Tarjan(y);
low[x]=min(low[x],low[y]);
if (low[y]>=dfn[x]){
Add_Edge(x,++k);
do {
Add_Edge(st[top],k);
} while (st[top--]!=y);
}
}
else
low[x]=min(low[x],dfn[y]);
}
int size[N],d[N];
void dfs(int x,int pre){
size[x]=x<=n;
int v=x<=n?-1:(int)t[x].size();
for (auto y : t[x])
if (y!=pre){
dfs(y,x);
ans+=2LL*v*size[x]*size[y];
size[x]+=size[y];
}
ans+=2LL*v*size[x]*(Size-size[x]);
}
int main(){
n=read(),m=read(),k=n;
For(i,1,m){
int x=read(),y=read();
e[x].pb(y),e[y].pb(x);
}
For(i,1,n)
if (!dfn[i])
Size=0,Tarjan(i),dfs(i,0);
cout<<ans<<endl;
return 0;
}
UOJ#416. 【APIO2018】铁人两项的更多相关文章
- [APIO2018]铁人两项 --- 圆方树
[APIO2018] 铁人两项 题目大意: 给定一张图,问有多少三元组(a,b,c)(a,b,c 互不相等)满足存在一条点不重复的以a为起点,经过b,终点为c的路径 如果你不会圆方树 ------- ...
- [APIO2018]铁人两项——圆方树+树形DP
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...
- [APIO2018]铁人两项 [圆方树模板]
把这个图缩成圆方树,把方点的权值设成-1,圆点的权值设成点双的size,算 经过这个点的路径的数量*这个点的点权 的和即是答案. #include <iostream> #include ...
- [APIO2018]铁人两项(圆方树)
过了14个月再重新看这题,发现圆方树从来就没有写过.然后写了这题发现自己APIO2018打铁的原因竟然是没开long long,将树的部分的O(n)写挂了(爆int),毕竟去年APIO时我啥都不会,连 ...
- 2019.03.29 bzoj5463: [APIO2018] 铁人两项(圆方树+树形dp)
传送门 题意简述:给你一张无向图,问你满足存在从a−>b−>ca->b->ca−>b−>c且不经过重复节点的路径的有序点对(a,b,c)(a,b,c)(a,b,c) ...
- LOJ.2587.[APIO2018]铁人两项Duathlon(圆方树)
题目链接 LOJ 洛谷P4630 先对这张图建圆方树. 对于S->T这条(些)路径,其对答案的贡献为可能经过的所有点数,那么我们把方点权值设为联通分量的大小,可以直接去求树上路径权值和. 因为两 ...
- [BZOJ5463][APIO2018]铁人两项:Tarjan+圆方树
分析 根据题目中的要求,从\(s\)出发前往\(f\)一定可以,并且只可能经过这两个结点所在的点双连通分量和它们之间的点双连通分量,因此切换点\(c\)只能从这些点中选取. 建出圆方树后,因为圆方树上 ...
- 洛谷P4630 [APIO2018]铁人两项 [广义圆方树]
传送门 又学会了一个新东西好开心呢~ 思路 显然,假如枚举了起始点\(x\)和终止点\(y\),中转点就必须在它们之间的简单路径上. 不知为何想到了圆方树,可以发现,如果把方点的权值记为双联通分量的大 ...
- [BZOJ5463] [APIO2018] 铁人两项
题目链接 LOJ. BZOJ. Solution 先建圆方树. 我们考虑暴力,枚举一个点对,我们枚举的点都是圆点,然后统计中间那个点可以取的位置的数量,加起来就是答案. 那么怎么统计呢,我们对于每个点 ...
- LOJ2587:[APIO2018]铁人两项——题解
https://loj.ac/problem/2587#submit_code (题面来自LOJ) 考试时候发觉树很可做,并且写了一个dp骗到了树的分. 苦于不会圆方树……现在回来发现这题还是很可做的 ...
随机推荐
- 复选框checkbox——用背景图片替换样式
input { border : none; display : inline-block; width : 25px; height : 25px; -webkit-apearance : none ...
- getopt()函数 命令解析
今天做计算机系统结构实验时学习到一个非常方便的命令解析函数getopt(),简单做个笔记,方便日后复习. 头文件:#include<unistd.h> 函数原型:int getopt(in ...
- C语言博客作业06——结构体&文件
C语言博客作业06--结构体&文件 1.本章学习总结 1.1思维导图 1.2.本章学习体会 在本周的学习中,我们学习了关于结构体和文件的内容.结构体的本身并不难,但以结构体为基础的链表还是让我 ...
- PageRank算法初探
1. PageRank的由来和发展历史 0x1:源自搜索引擎的需求 Google早已成为全球最成功的互联网搜索引擎,在Google出现之前,曾出现过许多通用或专业领域搜索引擎.Google最终能击败所 ...
- vscode中文配置说明
1.官网下载vscode安装完毕后, 2.在扩展中搜索chinese,选择:“Chinese (Simplified) Language Pack for Visual Studio Code” 3. ...
- J.U.C-volatile
禁止指令重排
- 2018-2019-2 《Java程序设计》第9周学习总结
20175319 2018-2019-2 <Java程序设计>第9周学习总结 教材学习内容总结 本周学习任务: 下载安装MySQL数据库管理系统. 教材介绍在官网下载安装Mysql服务,启 ...
- C++预编译头文件 – stdafx.h
预编译头文件的由来 也许请教了别的高手之后,他们会告诉你,这是预编译头,必须包含.可是,这到底是为什么呢?预编译头有什么用呢? 咱们从头文件的编译原理讲起.其实头文件并不神秘,其在编译时的作用,就是把 ...
- Python包中 __init__.py文件的作用
原创连接 https://www.cnblogs.com/AlwinXu/p/5598543.html Python包中 __init__.py文件的作用 在创建python包的过程中,IDE都会在包 ...
- Mask_RCNN学习记录(matterport版本)
资源链接 Mask R-CNN论文 matterport版本的GitHub 基于Keras和Tensorflow GitHub上还有Facebook的官方实现版本:Detectron maskrcnn ...