Luogu 2597 [ZJOI2012]灾难
BZOJ 2815。
解法还是挺巧妙的。
放上写得很详细很好懂的题解链接 戳这里。
一个物种$x$如果要灭绝,那么沿着它的入边反向走走走,一定可以走到一个点$y$,如果这个点$y$的物种灭绝了,那么$x$也一定会灭绝。而且,因为一次只能灭绝一个物种,只有满足这个条件这个物种$x$才会灭绝。
那么我们可以考虑建立一棵树,对于一个点$x$,将它能直接导致灭绝的点$y$作为它的直接儿子,然后我们统计一下每一个结点的$siz$再$- 1$就是答案了。
考虑一下如何找到这个走走走之后的关键点,因为这张图满足$DAG$的性质,我们可以一边拓扑排序一边建树,如果当前从队列里面取出了$x$,那么所有在$x$之前能走到的点一定在我们建的树里面了,我们只要在建好的树上找到所有直接连通$x$的点的$lca$作$x$的父亲就可以了。
插点的倍增$lca$,可以直接动态维护出来。
可以建一个超级源点连通所有的连通块。
时间复杂度$O(nlogn)$。
Code:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std; const int N = 1e5 + ;
const int Lg = ; int n, rt, tot = , head[N];
int q[N], fa[N][Lg], dep[N], deg[N], siz[N];
vector <int> G1[N], G2[N]; struct Edge {
int to, nxt;
} e[N << ]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void swap(int &x, int &y) {
int t = x; x = y; y = t;
} inline void prework(int x, int fat) {
dep[x] = dep[fat] + , fa[x][] = fat;
for(int i = ; i <= ; i++)
fa[x][i] = fa[fa[x][i - ]][i - ];
} inline int getLca(int x, int y) {
if(dep[x] < dep[y]) swap(x, y);
for(int i = ; i >= ; i--)
if(dep[fa[x][i]] >= dep[y])
x = fa[x][i];
if(x == y) return x;
for(int i = ; i >= ; i--)
if(fa[x][i] != fa[y][i])
x = fa[x][i], y = fa[y][i];
return fa[x][];
} inline void topSort() {
int l = , r = ; q[] = rt;
prework(rt, );
for(; l <= r; ) {
int x = q[++l], fat = , vecSiz = G2[x].size();
for(int i = ; i < vecSiz; i++) {
int y = G2[x][i];
if(!fat) fat = y;
else fat = getLca(fat, y);
}
if(x != rt) add(x, fat), add(fat, x);
prework(x, fat); vecSiz = G1[x].size();
for(int i = ; i < vecSiz; i++) {
int y = G1[x][i];
--deg[y];
if(!deg[y]) q[++r] = y;
}
}
} void dfs(int x, int fat) {
siz[x] = ;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
dfs(y, x);
siz[x] += siz[y];
}
} int main() {
read(n);
for(int x, i = ; i <= n; i++) {
for(read(x); x; read(x)) {
G1[x].push_back(i);
G2[i].push_back(x);
++deg[i];
}
} rt = n + ;
for(int i = ; i <= n; i++)
if(!deg[i]) {
G1[rt].push_back(i);
G2[i].push_back(rt);
++deg[i];
} topSort();
dfs(rt, ); for(int i = ; i <= n; i++)
printf("%d\n", siz[i] - ); return ;
}
Luogu 2597 [ZJOI2012]灾难的更多相关文章
- Luogu P2597 [ZJOI2012]灾难
一道非常综合的好题然后就莫名其妙地知道了动态LCA的求法 果然是ZJOI的题目,只能说这思路服了 首先我们发现每次操作只会灭绝一种动物,然后我们想一下就知道如果有\(n(n>=2)\)个食物的动 ...
- Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造
Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造 题意: 我们用一种叫做食物网的有向图来描述生物之间的关系:一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连 ...
- 【BZOJ2815】[ZJOI2012]灾难 拓扑排序+LCA
[BZOJ2815][ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从 ...
- [洛谷P2597] [ZJOI2012]灾难
洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...
- 1321. [ZJOI2012] 灾难
1321. [ZJOI2012] 灾难 ★★☆ 输入文件:catas.in 输出文件:catas.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 阿米巴是小强的 ...
- 洛谷 P2597 [ZJOI2012]灾难 解题报告
P2597 [ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发 ...
- P2597 [ZJOI2012]灾难——拓扑,倍增,LCA
最近想学支配树,但是基础还是要打好了的: P2597 [ZJOI2012]灾难 这道题是根据食物链链接出一个有向图的关系,求一个物种的灭绝会连带几种物种的灭绝: 求得就是一个点能支配几个点: 如果一个 ...
- 洛谷P2597 [ZJOI2012] 灾难 [拓扑排序,LCA]
题目传送门 灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. ...
- BZOJ 2815: [ZJOI2012]灾难
呃,题面没了,大概就是给出一些生物之间的捕食关系,求灭绝树每个点的灾难值. 拓扑排序之后倒着加入点,动态维护fa[][]数组,倍增法求LCA,当然大佬愿意写动态树也是极好的…… #include &l ...
随机推荐
- self = [super init] 最终解释
答: init 中调用super的 init方法来初始化自己所包含有的父类信息 1.内存分配 内存应该在[Class alloc]的时候就已经分配了,大小和类型应该由对应的Clas ...
- 如何手玩5h uoj215 果冻运输得到 AC
最近在大力练习提答颓提答,听说果冻运输很好玩就来试试. 然后玩的停不下来 QAQ ... 于是开一篇博客写一下每个点的解法.(一个个手玩出来的..) 首先我们每次都算什么下一步完后会发生什么在大脑中演 ...
- openfaas cli 安装
1. 安装脚本 curl -sL https://cli.get-faas.com/ | sudo sh 备注安装完成之后如果没有 faas-cli 可以下载脚本,手工执行 2. 使用二进制 ...
- 11g R2 rac linstener 监听配置
两个节点host,ipvip ,scan的信息 #eth0-Public IP 162.12.0.1 cqltjcpt1 162.12.0.3 cqltjcpt2 #eth1 PRIVAT ...
- 初上dubbo
编译异常 no groovy library is defined for module http://blog.csdn.net/lu_wei_wei/article/details/7601968 ...
- SERDES高速系统(二)
抖动.容忍度与功耗 前面我提到SERDES的最终性能要用传输速率和传输距离考核.使用眼图可以形象化地衡量SERDES的收发性能,但是更为精确的参数化衡量手段是抖动(Jitter).容忍度(Tolera ...
- jenkins获取测试报告展示的方法
1.写好了可以生成报告的python文件 2.在jenkins里下载 HTML Publisher plugin 插件 系统管理--管理插件--选择[可选插件]tab---搜索HTML Publis ...
- Linux下面的yum命令详解
yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RP ...
- mongodb基本操作和在springboot中的使用
本文介绍mongodb的使用 说明 起步 mongo通用类型 mongoshell的操作 CRUD操作 shell命令操作 索引操作 mongo在springboot中的使用 目录结构 依赖 prop ...
- redis学习六 集群的原理(转载)
转载自 http://shift-alt-ctrl.iteye.com/blog/2285470 一.Redis Cluster主要特性和设计 集群目标 1)高性能和线性扩展,最大可以支撑到1 ...