P2597 [ZJOI2012]灾难(倍增LCA+拓扑排序)
据大佬说这玩意儿好像叫灾难树还是灭绝树?
我们先按建图,设点$u$的食物有$x[1]...x[k]$,即在图中这些点都有一条指向它的边
以样例来说,对于人,羊和牛都有一条指向它的边,然而不管是羊的灭绝还是牛的灭绝都不会导致人的灭绝,会导致人灭绝的只有草,也就是羊和牛的LCA
(严格来说这个应该不叫LCA,不过反正这是一个有向无环图,大家能理解就好)
于是我们把人挂到草的下面,表示只有草的灭绝会使人灭绝。
于是我们按拓扑序把每一个生物都依次加入灭绝树,然后一遍dfs,每一个生物的灾难值就是它的子树的大小减一
//minamoto
#include<iostream>
#include<cstdio>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
int read(){
int res,f=;char ch;
while((ch=getc())>''||ch<'')(ch=='-')&&(f=-);
for(res=ch-'';(ch=getc())>=''&&ch<='';res=res*+ch-'');
return res;
}char sr[<<],z[];int C=-,Z=;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
void print(int x){
if(C><<)Ot();if(x<)sr[++C]='-',x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=;
int head[N<<],Next[N<<],ver[N<<],tot,head1[N<<],ver1[N<<],Next1[N<<],tot1,head2[N<<],ver2[N<<],Next2[N<<],tot2;
inline void add(int u,int v){ver[++tot]=v,Next[tot]=head[u],head[u]=tot;}
inline void add1(int u,int v){ver1[++tot1]=v,Next1[tot1]=head1[u],head1[u]=tot1;}
inline void add2(int u,int v){ver2[++tot2]=v,Next2[tot2]=head2[u],head2[u]=tot2;}
int n,du[N],q[N],dep[N],fa[N][],ans[N];
void topo(){
int h=,t=;
for(int i=;i<=n;++i)if(!du[i])q[++t]=i;
while(h<=t){
int u=q[h++];
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(--du[v]==)q[++t]=v;
}
}
}
int LCA(int u,int v){
if(dep[u]<dep[v])swap(u,v);int k=dep[u]-dep[v];
for(int i=;i<;++i)
if((k>>i)&)u=fa[u][i];
if(u==v)return u;
for(int i=;i>=;--i)
if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
return fa[u][];
}
void dfs(int u){
for(int i=head2[u];i;i=Next2[i])
dfs(ver2[i]),ans[u]+=ans[ver2[i]];
++ans[u];
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=,u;i<=n;++i){
while(true){
if((u=read())==)break;
++du[i],add1(i,u),add(u,i);
}
}
topo();
for(int i=;i<=n;++i){
int u=ver1[head1[q[i]]];
for(int j=head1[q[i]];j;j=Next1[j])u=LCA(u,ver1[j]);
add2(u,q[i]),dep[q[i]]=dep[u]+,fa[q[i]][]=u;
for(int j=;j<;++j)fa[q[i]][j]=fa[fa[q[i]][j-]][j-];
}
dfs();
for(int i=;i<=n;++i)print(ans[i]-);
return Ot(),;
}
P2597 [ZJOI2012]灾难(倍增LCA+拓扑排序)的更多相关文章
- Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造
Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造 题意: 我们用一种叫做食物网的有向图来描述生物之间的关系:一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连 ...
- [BZOJ2815][ZJOI2012]灾难 灭绝树+拓扑排序+lca
灾难 [问题描述] 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那 么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的 生态灾难. 学过 ...
- P2597 [ZJOI2012]灾难——拓扑,倍增,LCA
最近想学支配树,但是基础还是要打好了的: P2597 [ZJOI2012]灾难 这道题是根据食物链链接出一个有向图的关系,求一个物种的灭绝会连带几种物种的灭绝: 求得就是一个点能支配几个点: 如果一个 ...
- 洛谷 P2597 [ZJOI2012]灾难 解题报告
P2597 [ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发 ...
- 洛谷P2597 [ZJOI2012] 灾难 [拓扑排序,LCA]
题目传送门 灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. ...
- P2597 [ZJOI2012]灾难 拓扑排序
这个题有点意思,正常写法肯定会T,然后需要优化.先用拓扑排序重构一遍树,然后进行一个非常神奇的操作:把每个点放在他的食物的lca上,然后计算的时候直接dfs全加上就行了.为什么呢,因为假如你的食物的l ...
- [洛谷P2597] [ZJOI2012]灾难
洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...
- P2597 [ZJOI2012]灾难
\(\color{#0066ff}{ 题目描述 }\) 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝, ...
- Luogu P2597 [ZJOI2012]灾难
一道非常综合的好题然后就莫名其妙地知道了动态LCA的求法 果然是ZJOI的题目,只能说这思路服了 首先我们发现每次操作只会灭绝一种动物,然后我们想一下就知道如果有\(n(n>=2)\)个食物的动 ...
随机推荐
- node学习的一些网站
Node.js 包教不包会 篇幅比较少 node express 入门教程 nodejs定时任务 一个nodejs博客 [NodeJS 学习笔记04]新闻发布系统 过年7天乐,学nodejs 也快乐 ...
- 【03】emmet系列之CSS语法
[01]emmet系列之基础介绍 [02]emmet系列之HTML语法 [03]emmet系列之CSS语法 [04]emmet系列之编辑器 [05]emmet系列之各种缩写 单位: 有几个常用值别 ...
- C语言《一维数组的学习,冒泡排序》
#include<stdio.h> /* 一维数组的学习,冒泡排序 soulsjie 20170623 */ void main(){ int a[6]; int i,j,k; print ...
- 2018 & 微信小程序
2018 & 微信小程序 Wafer2 快速开发 Demo 本仓库是最简版的 Wafer2 开发套件,建议配合腾讯云微信小程序开发者工具解决方案一起使用.适用于想要使用 Wafer SDK 开 ...
- fzu 2113 数位dp
#include<stdio.h> #include<string.h> #define N 20 #define ll __int64 ll dp[N][N];//最多记忆4 ...
- 括号序列(Poj1141)
Poj1141 题目描述: 定义合法的括号序列如下: 1 空序列是一个合法的序列 2 如果S是合法的序列,则(S)和[S]也是合法的序列 3 如果A和B是合法的序列,则AB也是合法的序列 例如:下面的 ...
- hosts.allow和hosts.deny文件
之前想通过外部主机访问自己主机上的VMWare虚拟机,使用了VMWare的NAT端口映射,经过一番尝试,算是成功了,总结一下. VMWare NAT端口映射就可以将虚拟机上的服务映射成自己主机上的端口 ...
- Jquery为DIV添加点击事件,Jquery为a标签超链接添加点击事件
<div>1</div> <div>2</div> <div>3</div> <div>4</div> ...
- SQL SERVER 自增字段相关问题
SET IDENTITY_INSERT Data0048_TEST ON --给自增列赋值 DBCC CHECKIDENT(TableName) --查看某个表中的自增列当前的值 DBCC CHECK ...
- hihocoder1496(高维前缀和)
题意:给定N个数A1, A2, A3, ... AN,小Ho想从中找到两个数Ai和Aj(i ≠ j)使得乘积Ai × Aj × (Ai AND Aj)最大.其中AND是按位与操作. 第一行一个整数N( ...