1321. [ZJOI2012] 灾难

★★☆   输入文件:catas.in   输出文件:catas.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述】

阿米巴是小强的好朋友。

阿米巴和小强在草原上捉蚂蚱。小强突然想,如果蚂蚱被他们捉灭绝了,那

么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的

生态灾难。

学过生物的阿米巴告诉小强,草原是一个极其稳定的生态系统。如果蚂蚱灭

绝了,小鸟照样可以吃别的虫子,所以一个物种的灭绝并不一定会引发重大的灾

难。

我们现在从专业一点的角度来看这个问题。我们用一种叫做食物网的有向图

来描述生物之间的关系:

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

向 x 连一个有向边。

这个图没有环。

图中有一些点没有连出边,这些点代表的生物都是生产者,可以通过光合作

用来生存; 而有连出边的点代表的都是消费者,它们必须通过吃其他生物来生

存。

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

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

着一起灭绝的生物的种数。

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

如果小强和阿米巴把草原上所有的羊都给吓死了,那么狼会因为没有食物而

灭绝,而小强和阿米巴可以通过吃牛、牛可以通过吃草来生存下去。所以,羊的

灾难值是 1。但是,如果草突然灭绝,那么整个草原上的 5 种生物都无法幸免,

所以,草的灾难值是 4。

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

【输入格式】

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

号到 N。

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

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

表的结束。

【输出格式】

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

【样例输入】

5

0

1 0

1 0

2 3 0

2 0

【样例输出】

4

1

0

0

0

【样例说明】

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

【数据规模】

对 50%的数据,N ≤ 10000。

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

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

 #include <cstring>
#include <cstdio>
#include <queue>
#define cle(a,b) memset(a,b,sizeof a)
using namespace std;
int n;
struct edge
{
int v,next;
} e[]; int cnt;
int head[];
int thead[];
int HEAD[];
int t,u,v;
int fa[][],depth[];
int cause[];
int ts[],in[];
queue<int>q; void adde (int u,int v)
{
e[++cnt].v = v;
e[cnt].next = thead[u];
thead[u] = cnt;
e[++cnt].v = u;
e[cnt].next = head[v];
head[v] = cnt;
}
void read ()
{
cle(head,-);
cle(thead,-);
cle(HEAD,-);
scanf("%d",&n);
for(int i = ; i <= n; i++)
{
while(scanf("%d",&t),t)
{
adde(t,i);
in[i]++;
}
}
}
void topsort ()
{
t = ;
for(int i = ; i <= n; i++)
if(!in[i])
q.push(i);
while(!q.empty())
{
u = q.front();
q.pop();
ts[++t] = u;
for(int i = thead[u]; i != -; i = e[i].next)
{
v = e[i].v;
in[v]--;
if(!in[v])
q.push(v);
}
}
}
void go_up (int &u,int d)
{
int temp = ;
while(d)
{
if(( << temp) <= d)
{
d -= ( << temp);
u = fa[u][temp];
}
temp--;
}
}
int lca (int u,int v)
{
if(depth[u] != depth[v])
go_up(u,depth[u] - depth[v]);
if(u == v)
return u;
int temp = ;
do
{
if(fa[u][--temp] != fa[v][temp])
{
u = fa[u][temp];
v = fa[v][temp];
}
}
while(temp);
return fa[v][];
}
void ADDE (int u,int v)
{
e[++cnt].v = v;
e[cnt].next = HEAD[u];
HEAD[u] = cnt;
}
void build ()
{
for(int i = ; i <= n; i++)
{
t = -;
for(int j = head[ts[i]]; j != -; j = e[j].next)
{
if(t == -)
t = e[j].v;
else t = lca( depth[t] > depth[e[j].v] ? t : e[j].v , depth[t] > depth[e[j].v] ? e[j].v : t );
}
fa[ts[i]][] = t == - ? : t;
depth[ts[i]] = depth[t] + ;
ADDE(t,ts[i]);
for(int j = ; j <= ; j++)
fa[ts[i]][j] = fa[fa[ts[i]][j - ]][j - ];
}
}
void dfs (int U)
{
for(int i = HEAD[U]; i != -; i = e[i].next)
{
dfs(e[i].v);
cause[U] += cause[e[i].v] + ;
}
}
int main ()
{
freopen("catas.in","r",stdin);
freopen("catas.out","w",stdout);
read();
topsort();
build();
for(int i = ; i <= n; i++)
if(depth[i] == )
dfs(i);
for(int i = ; i <= n; i++)
printf("%d\n",cause[i]);
return ;
}

1321. [ZJOI2012] 灾难的更多相关文章

  1. Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造

    Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造 题意: 我们用一种叫做食物网的有向图来描述生物之间的关系:一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连 ...

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

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

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

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

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

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

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

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

  6. BZOJ 2815: [ZJOI2012]灾难

    呃,题面没了,大概就是给出一些生物之间的捕食关系,求灭绝树每个点的灾难值. 拓扑排序之后倒着加入点,动态维护fa[][]数组,倍增法求LCA,当然大佬愿意写动态树也是极好的…… #include &l ...

  7. BZOJ2815: [ZJOI2012]灾难

    传送门 学LCA的时候根本没意识到LCA可以有这么多玩法. 这玩意据说是个高级数据结构(支配树)的弱化版,蒟蒻没学过呀.所以出题人提出一个概念叫灾难树. 我理解的灾难树的意思实际上是属于DAG的一个子 ...

  8. 2815: [ZJOI2012]灾难 - BZOJ

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

  9. [ZJOI2012]灾难(建图)

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

随机推荐

  1. 【转载】#458 Errors While Converting Between enum and Underlying Type

    You can convert to an enum value from its underlying type by casting the underlying type (e.g. int) ...

  2. IOS VFL语言(页面布局)

    ● 什么是VFL语言 ● VFL全称是Visual Format Language,翻译过来是“可视化格式语言” ● VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言     VFL ...

  3. 从数据流角度管窥 Moya 的实现(一):构建请求

    相信大家都封装过网络层. 虽然系统提供的网络库以及一些著名的第三方网络库(AFNetworking, Alamofire)已经能满足各种 HTTP/HTTPS的网络请求,但直接在代码里用起来,终归是比 ...

  4. c#正则表达式最简demo

    各个语言的正则表达式规则略有不同 项目中用到,所以将这个最简单的demo记录 using System; using System.Collections.Generic; using System. ...

  5. yarn下资源配置

    http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.0.6.0/bk_installing_manually_book/content/rpm-ch ...

  6. c语言描述的链队列的基本操作

    #include<stdio.h> #include<stdlib.h> #define ok 0 #define error 1 //链队列特点在于不仅有链的头指针和尾指针, ...

  7. 金s办公软件web前端笔试题

    1. var arr = []; arr['a'] = 1; console.log(arr.length); // A arr['4'] = 2; console.log(arr.length); ...

  8. LeetCode11.盛最多水的容器 JavaScript

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线, ...

  9. 固定导航栏demo

    代码如下 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF- ...

  10. LinkedList---链表各种方法的实现

    public class ListExer2 { public static void main(String[] args) { LinkList list = new LinkList(); li ...