洛谷题目链接:[ZJOI2012]灾难

题目描述

阿米巴是小强的好朋友。

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

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

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

一个食物网有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。保证输入的食物网没有环。


一句话题意: 给出一个食物链网络,当一个物种的所有食物都灭绝了这个物种才会灭绝,问一个物种灭绝后会使多少个物种灭绝.


题解: 首先可以确定处理顺序:一定要按照食物链的拓扑序来处理(从被吃的物种到吃它的物种),这样才能保证某一个物种灭绝后不会对它吃的物种造成影响.

那么在处理某个物种灭绝后造成的影响该怎么算呢?

不难想到暴力模拟,从每个点出发,直接拓扑序累加答案,这样的做法是\(O(n^2)\)的.可能有人会想到直接做一遍拓扑排序统计答案,但是这样的话就无法保证统计答案的时候某个物种的每一个食物都已经灭绝了,从而导致答案错误.

那么显然我们枚举每个点算答案的过程是不能省略的.那么该怎么样优化复杂度呢?

这里我们可以将已经算完答案的物种加入一颗树中,如果一个\(A\)灭绝后\(B\)也会灭绝,就将\(B\)连向\(A\)的儿子.这样建树的话统计答案就非常方便了,一个物种灭绝的答案就是它的子树大小.

但是这样还是有问题:一个物种可能要有多个物种灭绝才会灭绝.这时我们就可以求出这个物种所有的食物的\(LCA\),也就是说只有这个\(LCA\)灭绝了,这个物种才会灭绝.比如说这张图(引用自\(Lance1ot\)的贴图):

只有1灭绝了4才会灭绝,这样的话就将4接到1下面就可以了.

所以我们可以每次以拓扑序顺序向树中加点,并每次更新\(LCA\)的倍增数组(这里选用倍增求解\(LCA\)是因为倍增比较好在线统计,而树剖在建树的过程是离线的,也就是我们在处理之前并不知道树的形态).最后建好树后直接一遍\(dfs\)遍历整颗树.

#include<bits/stdc++.h>
using namespace std;
const int N = 300000+5; int n, val[N], gup[N][25], dep[N], in[N]; vector <int> food[N], top[N], ch[N]; int gi(){
int ans = 0, f = 1; char i = getchar();
while(i<'0' || i>'9'){ if(i == '-') f = -1; i = getchar(); }
while(i>='0' && i<='9') ans = ans*10+i-'0', i = getchar();
return ans * f;
} int lca(int x, int y){
if(dep[x] < dep[y]) swap(x, y);
for(int i=20;i>=0;i--)
if(dep[gup[x][i]] >= dep[y]) x = gup[x][i];
if(x == y) return x;
for(int i=20;i>=0;i--)
if(gup[x][i] != gup[y][i]) x = gup[x][i], y = gup[y][i];
return gup[x][0];
} void solve(int x){
int LCA = food[x][0];
for(int i=1;i<food[x].size();i++) LCA = lca(LCA, food[x][i]);
ch[LCA].push_back(x), dep[x] = dep[LCA]+1, gup[x][0] = LCA;
for(int i=1;i<=20;i++) gup[x][i] = gup[gup[x][i-1]][i-1];
} void topsort(){
queue <int> q;
for(int i=1;i<=n;i++)
if(in[i] == 0) in[i]++, top[0].push_back(i), food[i].push_back(0);
q.push(0);
while(!q.empty()){
int x = q.front(); q.pop();
for(int i=0;i<top[x].size();i++)
if(--in[top[x][i]] == 0) solve(top[x][i]), q.push(top[x][i]);
}
} void dfs(int x, int f){
for(int i=0;i<ch[x].size();i++)
dfs(ch[x][i], x), val[x] += val[ch[x][i]];
} int main(){
// freopen("data.in", "r", stdin);
ios::sync_with_stdio(false);
int x; n = gi();
for(int i=1;i<=n;i++){
x = gi();
while(x) in[i]++, top[x].push_back(i), food[i].push_back(x), x = gi();
}
for(int i=1;i<=n;i++) val[i] = 1;
topsort(), dfs(0, -1);
for(int i=1;i<=n;i++) cout << val[i]-1 << endl;
return 0;
}

[洛谷P2597] [ZJOI2012]灾难的更多相关文章

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

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

  2. 洛谷P2597 [ZJOI2012] 灾难 [拓扑排序,LCA]

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

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

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

  4. Solution -「ZJOI2012」「洛谷 P2597」灾难

    \(\mathcal{Description}\)   link.   给定一个捕食网络,对于每个物种,求其灭绝后有多少消费者失去所有食物来源.(一些名词与生物学的定义相同 w.)   原图结点数 \ ...

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

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

  6. [洛谷P2610] [ZJOI2012]旅游

    洛谷题目链接:[ZJOI2012]旅游 题目描述 到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~ 经过一番抉择,两人决定将T国作为他们的目的地.T国的国土可以用一个 ...

  7. 【洛谷 P2597】 [ZJOI2012]灾难(LCA)

    题目链接 考虑建一棵树,使一个生物灭绝时他的子树都会灭绝,显然这样答案就是以每个点为根的子树大小-1. 为什么原图不是一棵树,因为一个生物可能会以多个生物为食,所以按拓扑序来建树,把每个遍历到的点的父 ...

  8. 洛谷 P2611 [ZJOI2012]小蓝的好友 解题报告

    P2611 [ZJOI2012]小蓝的好友 题目描述 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物--小蓝的好友. 在帮小 ...

  9. P2597 [ZJOI2012]灾难

    \(\color{#0066ff}{ 题目描述 }\) 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝, ...

随机推荐

  1. 给你的WP应用加上帮助文档

    背景 这算是Windows Phone编程回顾续篇, 接着给大家聊WP开发经验. 在开发了数个WP应用并发布后, 陆续收到很多反馈邮件, 其中接近一半的邮件是在问"某某功能有没有?" ...

  2. Thunder团队第一周 - Scrum会议5

    本节内容: 工作照片 会议时间 会议地点 会议内容 Todo list 燃尽图 Scrum会议5 小组名称:Thunder 项目名称:爱阅app Scrum Master:邹双黛 工作照片: 参会成员 ...

  3. 测试报告M2

    1,项目简介我们已经在第一次测试报告中说过,这一次主要说一下场景测试实例 1.1测试人员 测试人员包括团队开发小组成员以及特邀测试用户组. 1)  团队内部测试主要针对网站支持的各功能组件进行一一测试 ...

  4. lintcode-28-搜索二维矩阵

    搜索二维矩阵 写出一个高效的算法来搜索 m × n矩阵中的值. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每行的第一个数大于上一行的最后一个整数. 样例 考虑下列矩阵: [ [1, 3, ...

  5. iOS开发JOSNModel<optional>,<convertondemand>,<index>

    指定定义的key的类型 <optional>表示字段可选,例如 //链接字段是可选的,转换的时候允许link未空 @property (nonatomic,strong) NSString ...

  6. <hx>标签 字体自动加粗 自动换行

    <hx>标签 字体自动加粗 自动换行

  7. CentOS 转义字符

    常用转义字符 反斜杠(\):使反斜杠后面的一个变量变为单纯的字符串. 单引号(''):转义其中所有的变量为单纯的字符串. 双引号(""):保留其中的变量属性,不进行转义处理. 反引 ...

  8. 1193: [HNOI2006]马步距离

    1193: [HNOI2006]马步距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2027  Solved: 915[Submit][Statu ...

  9. 【刷题】BZOJ 5154 [Tjoi2014]匹配

    Description 有N个单身的男孩和N个单身女孩,男孩i和女孩j在一起得到的幸福值为Hij.一个匹配即对这N个男孩女孩的安排: 每个男孩恰好有一个女朋友,每个女孩恰好有一个男朋友.一个匹配的幸福 ...

  10. [洛谷P4822][BJWC2012]冻结

    题目大意:有一张$n(n\leqslant50)$个点$m(m\leqslant1000)$条边的无向图,可以使得$k$条边使得边权减半,求最短路 题解:分层图最短路 卡点:无 C++ Code: # ...