【bzoj2815】灾难[ZJOI2012](拓扑排序+lca)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2815
原版题解:http://fanhq666.blog.163.com/blog/static/8194342620124274154996/
首先这个生态系统里可能有多个生产者,所以我们可以让生产者吃一种构造出来的食物——阳光。
这道题的图没有环(不然还怎么叫食物网),所以我们可以用拓扑排序把从阳光到各级消费者的先后顺序求出来。
我们可以建出一个结构(可以证明这个结构是一棵树),生物x会因为生物y的灭绝而灭绝,当且仅当y是x的祖先。
因此,如果一种生物会灭绝,只能是因为它的所有食物的lca灭绝了,否则至少有一种食物不会灭绝,这种生物也能活下去,所以这种生物在树上的位置就是它所有食物的lca的孩子。
然后我们把树建出来之后每个节点的答案就是以他为根的子树的节点个数-1。
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
#include<queue>
#include<vector>
#define ll long long
ll read()
{
ll tmp=; char f=,c=getchar();
while(c<''||''<c){if(c=='-')f=-; c=getchar();}
while(''<=c&&c<=''){tmp=tmp*+c-''; c=getchar();}
return tmp*f;
}
using namespace std;
int fir[]={},ne[],to[],x[],y[];
int q[],vis[]={};
ll in[]={},cnt[];
int fa[][],dep[];
int n,m,tot=;
void add(int x,int y){to[++tot]=y; ne[tot]=fir[x]; fir[x]=tot;}
int lca(int x,int y)
{
int i;
if(dep[x]<dep[y]){int tmp=x; x=y; y=tmp;}
for(i=(int)(log(n)/log()+);i>=;i--)if(dep[x]-(<<i)>=dep[y])x=fa[x][i];
if(x==y)return x;
for(i=(int)(log(n)/log()+);i>=;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
int main()
{
int i,j;
n=read();
for(i=;i<=n;i++){
int k=read();
if(!k)add(,i),in[i]=,x[tot]=i,y[tot]=;
while(k){++in[i]; add(k,i); x[tot]=i; y[tot]=k; k=read();}
}
int h=,t=; q[]=; vis[]=;
while(h<=t){
for(i=fir[q[h]];i;i=ne[i]){
--in[to[i]];
if(!in[to[i]])q[++t]=to[i],in[to[i]]=<<;
}
++h;
}
m=tot; tot=;
for(i=;i<=n;i++)fir[i]=;
for(i=;i<=m;i++)add(x[i],y[i]);
for(i=;i<=n;i++)
for(j=;<<j<=n;j++)
fa[i][j]=-;
fa[][]=-; dep[]=;
for(i=;i<=n;i++){
int p=-;
for(j=fir[q[i]];j;j=ne[j])
if(p==-)p=to[j];else p=lca(p,to[j]);
fa[q[i]][]=p; dep[q[i]]=dep[p]+;
for(j=;<<j<=n&&fa[fa[q[i]][j-]][j-]>=;j++)fa[q[i]][j]=fa[fa[q[i]][j-]][j-];
}
for(i=;i<=n;i++)cnt[i]=;
for(i=n;i;i--)cnt[fa[q[i]][]]+=cnt[q[i]];
for(i=;i<=n;i++)
printf("%lld\n",cnt[i]-);
}
bozj2815
【bzoj2815】灾难[ZJOI2012](拓扑排序+lca)的更多相关文章
- 【题解】 [ZJOI2012]灾难 (拓扑排序+LCA)
懒得复制,戳我戳我 Solution: 这题思路很神奇,首先你要知道这个毁灭树是怎么保证实现的:一句话就是如果该节点要被破坏,他的所有父节点就要被破坏,也就只要所有父节点的LCA被破坏就可以,所以我们 ...
- 【BZOJ2815】[ZJOI2012]灾难 拓扑排序+LCA
[BZOJ2815][ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从 ...
- BZOJ2815:[ZJOI2012]灾难(拓扑排序,LCA)
Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...
- [BZOJ2815][ZJOI2012]灾难 灭绝树+拓扑排序+lca
灾难 [问题描述] 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那 么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的 生态灾难. 学过 ...
- BZOJ2815 拓扑排序 + LCA
https://www.lydsy.com/JudgeOnline/problem.php?id=2815 作为一个DAG图,结点之间又有这么明显的等级之分,很容易想到的是拓扑排序. 但是不管是正向的 ...
- 【bzoj2815】[ZJOI2012]灾难 拓扑排序+倍增LCA
题目描述(转自洛谷) 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过生物 ...
- 洛谷P2597 [ZJOI2012] 灾难 [拓扑排序,LCA]
题目传送门 灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. ...
- [BZOJ2815][ZJOI2012]灾难(拓扑排序/支配树)
支配树目前只见到这一个应用,那就不独分一类,直接作为拓扑排序题好了. 每个点向所有食物连边,定义fa[x]为x的支配点,即离x最近的点,满足若fa[x]灭绝,则x也要灭绝. 这样,将fa[x]向x连边 ...
- P2597 [ZJOI2012]灾难 拓扑排序
这个题有点意思,正常写法肯定会T,然后需要优化.先用拓扑排序重构一遍树,然后进行一个非常神奇的操作:把每个点放在他的食物的lca上,然后计算的时候直接dfs全加上就行了.为什么呢,因为假如你的食物的l ...
随机推荐
- linux下shell程序(一)
shell结构 1.#!指定执行脚本的shell 2.#注释行 3.命令和控制结构 创建shell程序的步骤 第一步:创建一个包含命令和控制结构的文件. 第二步:修改这个文件的权限使它可以执行.使用c ...
- PHP 规划(收藏的一些好博文)
2014-10-15 01:30 36870人阅读 评论(34) 收藏 举报 分类: PHP/DHTML/Other(237) 版权声明:本文为博主原创文章,未经博主允许不得转载. PHP程序员的技术 ...
- Python将数据保存到CSV中
#coding:utf-8import csv headers = ['ID','UserName','Password','Age','Country'] rows = [(1001,'qiye', ...
- dict字典使用方法
keys(). values() .items()方法 1.返回格式 dict_keys. dict_values 和 dict_items 2.常用于循环.迭代 for key in dict_te ...
- 哈工大LTP
http://ltp.ai/ http://pyltp.readthedocs.io/zh_CN/latest/ http://www.cnblogs.com/Denise-hzf/p/6612886 ...
- 2588: Spoj 10628. Count on a tree
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5766 Solved: 1374 ...
- SVN中分支的建立与合并
转载 出处:http://yaozhong1988.blog.163.com/blog/static/141737885201162671635126/ 一. SVN分支的意义: 简单 ...
- java中的四种权限
1.私有权限(private) private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类).被private修饰的成员,只能在定义它们的类中使用,在其他类中不能调用. ...
- Introduction to Mathematical Thinking - Week 2
基本数学概念 real number(实数):是有理数和无理数的总称 有理数:可以表达为两个整数比的数(a/b, b!=0) 无理数是指除有理数以外的实数 imply -- 推导出 不需要 A 能推导 ...
- 通过margin负值去除padding
.pay-type { // 图片布局前通过margin负值去除padding margin: 0 -@page-padding-horizontal; display: inline-flex; } ...