博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[2018.12.28]BZOJ2815 [ZJOI2012]灾难
阅读量:6582 次
发布时间:2019-06-24

本文共 1096 字,大约阅读时间需要 3 分钟。

首先,我们需要把图上的边像样例的图片一样反着建。

然后我们跑一遍拓扑排序(注意这时候可能有多个入度为0的点),记录每个点的层数(即它的所有父亲的层数最大值+1)。

然后我们将所有点按层数升序排序,依次处理。

对于每个点,能够使它灭绝的,深度最大的点是它所有父亲的\(LCA\),记为\(f_{i,0}\)

当然必然会有某一些点的所有父亲没有\(LCA\),或者它干脆没有父亲(①)。

这里就是要按层数处理节点的原因,可以确保处理一个点时,它所有的父亲都被处理过了。

显然\(f_{f_{i,0},0},f_{f_{f_{i,0},0},0},...\)也能使\(i\)灭绝。

由于\(f_{i,0}\)是唯一的,所以如果我们建一个新的图,其中所有\(f_{i,0}\)\(i\)连边,就得到了一个森林。

森林中所有树的根都满足①,而且所有满足①的点必然是树根。

而一个点的灾难值就是它的子树中点的数量。

code:

#include
using namespace std;int n,t,in[65551],sq[65551],sz,f[65551][20],ans[65551],dep[65551],tg;vector
e[65551];vector
fs[65551];vector
ze[65551];queue
q;void Tpst(){ for(int i=1;i<=n;i++)if(!in[i])q.push(i); while(!q.empty()){ sq[++sz]=t=q.front(); q.pop(); for(int i=0;i
=0;i--)if(dep[x]-(1<
=dep[y])x=f[x][i]; for(int i=16;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; if(x==y)return x; return f[x][0];}void dfs(int x){ ans[x]=1; for(int i=0;i

转载于:https://www.cnblogs.com/xryjr233/p/BZOJ2815.html

你可能感兴趣的文章
已发布13集网站开发技术视频:http://blog.sina.com.cn/s/blog_67d27f340102vf7l.html
查看>>
Mysql ibdata 丢失或损坏如何通过frm&ibd 恢复数据
查看>>
MySQL数据库的优化(二)
查看>>
Deepin OS和WIN7双启动 花屏原因一例
查看>>
UIMenuController—为UITextField禁用UIMenuController功能
查看>>
Protobuf使用不当导致的程序内存上涨问题
查看>>
【原创】扯淡的Centos systemd与Docker冲突问题
查看>>
Spring+Mybatis多数据库的配置
查看>>
给大家推荐一个免费下载名称读写ntfs软件的地方
查看>>
在MySQL数据库建立多对多的数据表关系
查看>>
突然停电或死机导致没保存的文件怎么找回
查看>>
kudu
查看>>
jquery.validate.min.js表单验证使用
查看>>
在JS中捕获console.log的输出
查看>>
Python扫描IP段指定端口是否开放(一次扫描20个B网段没问题)
查看>>
一些常用的WebServices
查看>>
CentOS7使用firewalld打开关闭防火墙与端口
查看>>
maven 添加阿里云maven镜像
查看>>
mac上安装consolas字体
查看>>
对向量、矩阵求导
查看>>