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骗到了树的分. 苦于不会圆方树……现在回来发现这题还是很可做的 ...
随机推荐
- H5_0002:微信分享设置
1,非公众号的链接,设置分享的预览图片. 先打开页面,在收藏页面,最后在收藏界面长按 “转发” ,即可在链接上出现预览图片.
- 你真的了解word-wrap和word-break的区别吗?
这两个东西是什么,我相信至今还有很多人搞不清,只会死记硬背的写一个word-wrap:break-word;word-break:break-all;这样的东西来强制断句,又或者是因为这两个东西实在是 ...
- Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) B. Weakened Common Divis
题目链接 让你找一个数,使得这个数,可以被每个二元组的两个数中的一个数整除. 先将第一个二元组的两个数质因数分解一下,分解的质数加入set中,然后,对剩下的n-1个二元组进行遍历,每次遍历到的二元组对 ...
- vue老司机
你和答案之间只差一个关键字 1.对象二级查找值渲染早于数据获取 解决vue.js 数据渲染成功仍报错的问题
- The SetStack Computer UVA - 12096
题意:初始状态的栈内包含一个空集,对栈进行一下操作: PUSH:向栈内压入一个空集 DUP:复制栈顶,并压入栈内 UNION:将栈顶端两个集合出栈,并将两个元素的并集入栈 INTERSECT:将栈顶端 ...
- Object类中方法详解
目录 概述 hashCode方法 getClass方法 toString方法 equals方法 clone方法 finalize方法 概述 Object 是类层次结构的根类.每个类都使用 Object ...
- 删除Win10资源管理器中的3D对象/音乐/视频文件夹
Win10如何删除资源管理器中的3D对象/音乐/视频等文件夹?使用Win10系统的用户都知道,打开此电脑之后,资源管理上面会显示文档/音乐/视频等7个文件夹,一些用户认为很少使用到它们,想要除之而后快 ...
- memcache的基本操作
1.linux下启动memcache [root@localhost ~]# memcached -d -m 512 -u root -p 12266 -c 256 参数名称及意义: -d 以守护 ...
- 马拉车算法——poj3974
https://segmentfault.com/a/1190000008484167?tdsourcetag=s_pctim_aiomsg 讲的超好! manacher算法理解 回文串分为偶回文串和 ...
- MySQL/Oracle数据库优化总结
MySQL数据库优化的八种方式 1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能 ...