Luogu P2597 [ZJOI2012]灾难
一道非常综合的好题然后就莫名其妙地知道了动态LCA的求法
果然是ZJOI的题目,只能说这思路服了
首先我们发现每次操作只会灭绝一种动物,然后我们想一下就知道如果有\(n(n>=2)\)个食物的动物就不会灭绝。
然后我们YY一个叫灭绝树的东西,在这个树上的点都满足一个性质:当一个节点被割去时,以它为根的整棵子树对应的动物都会灭亡。
然后我们只需要考虑如何搞出这个树了。
然后我们再YY一个虚拟节点0,让它向所有生产者连边,我们可以形象得理解成太阳。
然后我们将题目中的树反向建边,然后就变成了这样:

然后我们发现5号点很难受,因为有两个点连向它。那么如果只割一个点怎么让5号点灭绝。
答案很简单:只需要让它的两个父节点都灭绝即可
然后我们看要让2,3号点都灭绝,那么:

只需要让1灭绝即可。那么1与2,3的关系就很简单了:1是2,3的LCA
那么就很好办了,我们只需要按顺序找出每一个点的所有父节点的LCA,然后在灭绝树上把这个点挂在它的LCA下面即可。
但是这个顺序怎么办,我们注意到题目中提到了:
这个图没有环。
然后就我们从0开始拓扑排序即可确定这个顺序,然后就只求LCA了
这里注意因为我们没有刚开始就把图建出来,所以DFS序+RMQ和Tarjan的方法就不能用了。
所以我们用倍增,每次将一个点挂上树时然后单独更新它的LCA信息
然后就可以解决了,不得不吐槽一下这道题开了三个邻接表,还是很狗的,因为这个调了很久
CODE
#include<cstdio>
#include<cstring>
using namespace std;
const int N=70000,P=20;
struct edge
{
int to,next;
}e[N<<2],re[N<<2],new_e[N<<1];
int head[N],rhead[N],new_head[N],dep[N],ru[N],q[N],father[N][P],size[N],tot,sum,cnt,rcnt,new_cnt,n,x,rt;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void write(int x)
{
if (x/10) write(x/10);
putchar(x%10+'0');
}
inline void add(int x,int y)
{
e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
}
inline void radd(int x,int y)
{
re[++rcnt].to=y; re[rcnt].next=rhead[x]; rhead[x]=rcnt;
}
inline void new_add(int x,int y)
{
new_e[++new_cnt].to=y; new_e[new_cnt].next=new_head[x]; new_head[x]=new_cnt;
}
inline void swap(int &a,int &b)
{
int t=a; a=b; b=t;
}
inline void top_sort(void)
{
register int i; int H=0,T=0;
for (i=1;i<=n;++i)
if (!ru[i]) q[++T]=i,father[i][0]=rt,dep[i]=1,new_add(rt,i),new_add(i,rt);
while (H<T)
{
int now=q[++H];
for (i=head[now];i!=-1;i=e[i].next)
if (!(--ru[e[i].to])) q[++T]=e[i].to;
}
}
inline void rebuild(int now)
{
for (register int i=0;i<P-1;++i)
if (father[now][i]^-1) father[now][i+1]=father[father[now][i]][i];
}
inline int LCA(int x,int y)
{
register int i;
if (dep[x]<dep[y]) swap(x,y);
for (i=P-1;i>=0;--i)
if (father[x][i]^-1&&dep[father[x][i]]>=dep[y]) x=father[x][i];
if (!(x^y)) return x;
for (i=P-1;i>=0;--i)
if (father[x][i]^-1&&father[y][i]^-1&&father[x][i]^father[y][i]) x=father[x][i],y=father[y][i];
return father[x][0];
}
inline void get_tree(void)
{
register int i,j;
for (i=1;i<=n;++i)
{
int now=q[i];
if (!(father[now][0]^-1))
{
int fa=-1;
for (j=rhead[now];j!=-1;j=re[j].next)
if (fa^-1) fa=LCA(fa,re[j].to); else fa=re[j].to;
if (!(fa^-1)) fa=0;
father[now][0]=fa; new_add(fa,now); new_add(now,fa); dep[now]=dep[fa]+1; rebuild(now);
}
}
}
inline void DFS(int now,int fa)
{
size[now]=1;
for (register int i=new_head[now];i!=-1;i=new_e[i].next)
if (new_e[i].to^fa) DFS(new_e[i].to,now),size[now]+=size[new_e[i].to];
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(n); memset(father,-1,sizeof(father));
memset(e,-1,sizeof(e)); memset(head,-1,sizeof(head));
memset(re,-1,sizeof(re)); memset(rhead,-1,sizeof(rhead));
memset(new_e,-1,sizeof(new_e)); memset(new_head,-1,sizeof(new_head));
for (i=1;i<=n;++i)
for (read(x);x;read(x))
add(x,i),radd(i,x),++ru[i];
top_sort(); get_tree(); DFS(rt,-1);
for (i=1;i<=n;++i)
write(size[i]-1),putchar('\n');
return 0;
}
Luogu P2597 [ZJOI2012]灾难的更多相关文章
- 洛谷 P2597 [ZJOI2012]灾难 解题报告
P2597 [ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发 ...
- P2597 [ZJOI2012]灾难——拓扑,倍增,LCA
最近想学支配树,但是基础还是要打好了的: P2597 [ZJOI2012]灾难 这道题是根据食物链链接出一个有向图的关系,求一个物种的灭绝会连带几种物种的灭绝: 求得就是一个点能支配几个点: 如果一个 ...
- [洛谷P2597] [ZJOI2012]灾难
洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...
- 洛谷P2597 [ZJOI2012] 灾难 [拓扑排序,LCA]
题目传送门 灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. ...
- P2597 [ZJOI2012]灾难
\(\color{#0066ff}{ 题目描述 }\) 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝, ...
- P2597 [ZJOI2012]灾难(倍增LCA+拓扑排序)
传送门 据大佬说这玩意儿好像叫灾难树还是灭绝树? 我们先按建图,设点$u$的食物有$x[1]...x[k]$,即在图中这些点都有一条指向它的边 以样例来说,对于人,羊和牛都有一条指向它的边,然而不管是 ...
- P2597 [ZJOI2012]灾难 拓扑排序
这个题有点意思,正常写法肯定会T,然后需要优化.先用拓扑排序重构一遍树,然后进行一个非常神奇的操作:把每个点放在他的食物的lca上,然后计算的时候直接dfs全加上就行了.为什么呢,因为假如你的食物的l ...
- [bzoj2815] [洛谷P2597] [ZJOI2012] 灾难
Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...
- Luogu 2597 [ZJOI2012]灾难
BZOJ 2815. 解法还是挺巧妙的. 放上写得很详细很好懂的题解链接 戳这里. 一个物种$x$如果要灭绝,那么沿着它的入边反向走走走,一定可以走到一个点$y$,如果这个点$y$的物种灭绝了,那么 ...
随机推荐
- [20170625]12c Extended statistics.txt
[20170625]12c Extended statistics.txt --//别人的系统12c,awr报表出现大量调用执行如下sql语句.select default$ from col$ wh ...
- Source Insight 查找的选择项
查找参数:whole words only : 全字匹配查找case sensitive : 区分大小写project wide ...
- SSD 下的 MySQL(5.5) IO 优化
一 目录 一 目录 二 背景 三 SSD 特性 四 基于 SSD 的数据库优化 五 A 项目 MySQL 主从关系图 六 程序切换之前调优 6.1 修改系统 IO 调度算法 6.2 修改 innodb ...
- WampServer 安装使用详解
WampServer集成环境的搭建.安装.使用.配置 什么是WampServer WampServer是一款由法国人开发的Apache Web服务器.PHP解释器以及MySQL数据库的整合软件包.免去 ...
- 3.8Python数据处理篇之Numpy系列(八)---Numpy的梯度函数
目录 目录 前言 (一)函数说明 (二)一维数组的应用 (三)多维数组的应用 目录 前言 梯度函数,其中的梯度也就是斜率,反映的是各个数据的变化率.在numpy中只有一个梯度函数. (一)函数说明 ( ...
- ccf-20170303--Markdown
我的想法如下图: 代码和题目如下: 问题描述 试题编号: 201703-3 试题名称: Markdown 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 Markdown 是一 ...
- 基于SpringCloud的服务注册和调用
一:服务的注册和发现 Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry(注册登记)和Service Discovery(发现)实现.也是s ...
- ST_Geometry效率的测试与分析
测试环境 数据库:Oracle11g R1(11.1.0.6) 64Bit 中间件:ArcSDE10 (64Bit) 数据情况:点数据(point,231772条记录),面数据(poly,12条记录) ...
- vs2015添加管理员权限
在工作过程中,我可能可能遇到要求编译好的程序默认以管理员权限运行,我们可以这样操作 一.新建一个manifest文件: <?xml version="1.0" encodin ...
- forever start app.js 启动node时,服务访问一次后第二次就不能访问了
开始总是找不到原因,是因为在启动服务时,没有设置日志文件.突然想到了是不是forever安装的有问题,就重新安装forever , 这时候提示系统 no space left on device , ...