题目传送门

灾难

题目描述

阿米巴是小强的好朋友。

阿米巴和小强在草原上捉蚂蚱。小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难。

学过生物的阿米巴告诉小强,草原是一个极其稳定的生态系统。如果蚂蚱灭绝了,小鸟照样可以吃别的虫子,所以一个物种的灭绝并不一定会引发重大的灾难。

我们现在从专业一点的角度来看这个问题。我们用一种叫做食物网的有向图来描述生物之间的关系:

一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连一个有向边。

这个图没有环。

图中有一些点没有连出边,这些点代表的生物都是生产者,可以通过光合作用来生存; 而有连出边的点代表的都是消费者,它们必须通过吃其他生物来生存。

如果某个消费者的所有食物都灭绝了,它会跟着灭绝。

我们定义一个生物在食物网中的“灾难值”为,如果它突然灭绝,那么会跟着一起灭绝的生物的种数。

举个例子:在一个草场上,生物之间的关系是:

如 

如果小强和阿米巴把草原上所有的羊都给吓死了,那么狼会因为没有食物而灭绝,而小强和阿米巴可以通过吃牛、牛可以通过吃草来生存下去。所以,羊的灾难值是1。但是,如果草突然灭绝,那么整个草原上的5种生物都无法幸免,所以,草的灾难值是4。

给定一个食物网,你要求出每个生物的灾难值。

输入输出格式

输入格式:

输入文件 catas.in 的第一行是一个正整数 N,表示生物的种数。生物从 1 标

号到 N。

接下来 N 行,每行描述了一个生物可以吃的其他生物的列表,格式为用空

格隔开的若干个数字,每个数字表示一种生物的标号,最后一个数字是 0 表示列

表的结束。

输出格式:

输出文件catas.out包含N行,每行一个整数,表示每个生物的灾难值。

输入输出样例

输入样例#1:

5
0
1 0
1 0
2 3 0
2 0
输出样例#1:

4
1
0
0
0

说明

【样例说明】

样例输入描述了题目描述中举的例子。

【数据规模】

对50%的数据,N ≤ 10000。

对100%的数据,1 ≤ N ≤ 65534。

输入文件的大小不超过1M。保证输入的食物网没有环。


  分析:

  看懂题意后很自然朝着拓扑排序的方向想,那么在拓扑的过程中我们怎么记录节点对答案的贡献呢?

  实际上这道题在拓扑排序的过程中是没办法记录节点对答案的贡献的,那么就换一种思路,在拓扑排序过程中我们把这张图重建成一棵树,树上某个节点的祖先就是灭绝以后会波及到这个节点的节点,那么我们就只需要在拓扑过程中同时在树上动态维护$LCA$(这里跳$LCA$只要暴力跳就行了),最后做树上前缀和求答案就行了。具体实现看代码。

  Code:

//It is made by HolseLee on 13th Oct 2018
//Luogu.org P2012
#include<bits/stdc++.h>
using namespace std; const int N=2e6+;
int n,head[N],cnte,fa[N],lca[N],h[N],cnt,ans[N],dg[N],dep[N];
struct Edge {
int to,nxt;
}e[N<<],edge[N<<];
queue<int>t; inline int read()
{
char ch=getchar(); int num=; bool flag=false;
while( ch<'' || ch>'' ) {
if( ch=='-' ) flag=false; ch=getchar();
}
while( ch>='' && ch<='' ) {
num=num*+ch-''; ch=getchar();
}
return flag ? -num : num;
} inline void add(int x,int y)
{
e[++cnte].to=y;
e[cnte].nxt=head[x];
head[x]=cnte;
} inline void add_edge(int x,int y)
{
edge[++cnt].to=y;
edge[cnt].nxt=h[x];
h[x]=cnt;
} inline int LCA(int x,int y)
{
if( !x || !y ) return ;
if( dep[x]<dep[y] ) swap(x,y);
while( dep[x]>dep[y] ) x=fa[x];
while( x!=y ) x=fa[x], y=fa[y];
return x;
} void dfs(int x)
{
for(int i=h[x],y; i; i=edge[i].nxt) {
y=edge[i].to;
dfs(y);
ans[x]+=(ans[y]+);
}
} int main()
{
memset(lca,-,sizeof(lca));
n=read();
int x,y;
for(int i=; i<=n; ++i) {
while( ) {
x=read(); if( !x ) break;
add(x,i); dg[i]++;
}
}
for(int i=; i<=n; ++i)
if( !dg[i] ) t.push(i),add_edge(,i),fa[i]=,dep[i]=;
while( !t.empty() ) {
x=t.front(); t.pop();
for(int i=head[x]; i; i=e[i].nxt) {
y=e[i].to; dg[y]--;
if( lca[y]==- ) lca[y]=x;
else lca[y]=LCA(lca[y],x);
if( !dg[y] ) t.push(y),dep[y]=dep[lca[y]]+, add_edge(lca[y],y),fa[y]=lca[y];
}
}
dfs();
for(int i=; i<=n; ++i) printf("%d\n",ans[i]);
return ;
}

洛谷P2597 [ZJOI2012] 灾难 [拓扑排序,LCA]的更多相关文章

  1. 洛谷 P2597 [ZJOI2012]灾难 解题报告

    P2597 [ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发 ...

  2. [洛谷P2597] [ZJOI2012]灾难

    洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...

  3. 【BZOJ2815】[ZJOI2012]灾难 拓扑排序+LCA

    [BZOJ2815][ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从 ...

  4. BZOJ2815:[ZJOI2012]灾难(拓扑排序,LCA)

    Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...

  5. P2597 [ZJOI2012]灾难 拓扑排序

    这个题有点意思,正常写法肯定会T,然后需要优化.先用拓扑排序重构一遍树,然后进行一个非常神奇的操作:把每个点放在他的食物的lca上,然后计算的时候直接dfs全加上就行了.为什么呢,因为假如你的食物的l ...

  6. [bzoj2815] [洛谷P2597] [ZJOI2012] 灾难

    Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...

  7. P2597 [ZJOI2012]灾难——拓扑,倍增,LCA

    最近想学支配树,但是基础还是要打好了的: P2597 [ZJOI2012]灾难 这道题是根据食物链链接出一个有向图的关系,求一个物种的灭绝会连带几种物种的灭绝: 求得就是一个点能支配几个点: 如果一个 ...

  8. 【bzoj2815】[ZJOI2012]灾难 拓扑排序+倍增LCA

    题目描述(转自洛谷) 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过生物 ...

  9. 【bzoj2815】灾难[ZJOI2012](拓扑排序+lca)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2815 原版题解:http://fanhq666.blog.163.com/blog/st ...

随机推荐

  1. spring断言使用

    断言就是断定某一个实际的值为自己预期想得到的,如果不一样就抛出异常. Assert经常用于: 1.判断method的参数是否属于正常值.2.juit中使用. import org.springfram ...

  2. Java编程思想 4th 第1章 对象导论

    所有编程语言都提供抽象机制. 面向对象编程似乎是一种很好的编程思想和方式,面向对象编程中的对象简洁描述是:对象具有状态.行为和标识.状态指的是数据存储,存储的数据能反应状态:行为指的是方法,方法表示对 ...

  3. Android Build.VERSION.SDK_INT兼容介绍

    尽管Android向下兼容不好,但是一个程序还是可以在多个平台上跑的.向下兼容不好,接口改变,新的平台上不能用旧的API,旧的平台更不可能用新的API,不等于一个平台需要一个APK.可以在高SDK上开 ...

  4. 莫烦课程Batch Normalization 批标准化

    for i in range(N_HIDDEN): # build hidden layers and BN layers input_size = 1 if i == 0 else 10 fc = ...

  5. PE文件结构及其加载机制

    一.PE文件结构 PE即Portable Executable,是win32环境自身所带的执行体文件格式,其部分特性继承自Unix的COFF(Common Object File Format)文件格 ...

  6. 内核工具 – Sparse 简介【转】

    转自:http://www.cnblogs.com/wang_yb/p/3575039.html Sparse是内核代码静态分析工具, 能够帮助我们找出代码中的隐患. 主要内容: Sparse 介绍 ...

  7. 一个不错的linux学习资料下载的网址

    本文比较完整的讲述GNU make工具,涵盖GNU make的用法.语法.同时重点讨论如何为一个工程编写Makefile.作为一个Linux程序员,make工具的使用以及编写Makefile是必需的. ...

  8. VC++ 编译libcurl 支持SSL,GZIP

    由于网上下载的 libcurl 不支持 gzip,只好自己动手编译,期间走了很多弯路,下面是最终成功的记录. 我所使用的环境 Visual Studio 2010 . Windows 7 64 bit ...

  9. python网络编程--线程join和Daemon(守护进程)

    一:什么情况下使用join join([timeout])调用join函数会使得主调线程阻塞,直到被调用线程运行结束或超时. 参数timeout是一个数值类型,用来表示超时时间,如果未提供该参数,那么 ...

  10. java基础54 网络通讯的三要素及网络/网页编程的概述

    1.概述 网络编程注意解决的是计算机(手机.平板.....)之间的数据传输问题.        网络编程:不需要基于html基础上,就可以进行数据间的传输.比如:FeiQ.QQ.微信.....     ...