一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连一个有向边。这个图没有环。图中有一些点没有连出边,这些点代表的生物都是生产者,可以通过光合作用来生存; 而有连出边的点代表的都是消费者,它们必须通过吃其他生物来生存。如果某个消费者的所有食物都灭绝了,它会跟着灭绝。我们定义一个生物在食物网中的“灾难值”为,如果它突然灭绝,那么会跟着一起灭绝的生物的种数。现在请你求出每一个物种的“灾难值”。

  首先思考:什么情况下一个物种会灭绝?也就是所有它能吃的东西灭绝了,它就灭绝了。所以如果要让物种A灭绝,我们可以选一个物种B,使得物种A所有能吃的东西都灭绝。我们定义”灭绝树”,其中一个节点的父亲是能让它灭绝的深度最低的结点。不难发现灭绝树上A的祖先灭绝后,A一定灭绝。所以若要让物种x,y一起灭绝,只需查询它们所有父亲在灭绝树上的lca即可。

  这道题做了三天。。最后用cyaron对拍出来,发现是一个以前写的模块忘记改回来了。。以后写程序就要一口气写完,不要被外界干扰。

 #include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std; const int maxn=; int first1[maxn], first2[maxn], topo[maxn], topo2[maxn], out[maxn];
int fa[maxn][], dep[maxn], size[maxn], ans[maxn];
struct Edge{
int v, to, next;
};
Edge edges1[maxn], edges2[maxn]; int n, cnte1, cnte2; void addedge(int *first, Edge *edges, int &cntedge,
int v, int from, int to){
edges[cntedge].v=v;
edges[cntedge].to=to;
edges[cntedge].next=first[from];
first[from]=cntedge;
cntedge++;
return;
} double log2(int x){
return log(x)/log();
} int get_lca(int x, int y){
int t=, step=;
if (dep[x]<dep[y]) swap(x, y);
t=dep[x]-dep[y];
while (t){
if (t&) x=fa[x][step];
t>>=;
++step;
}
for (int step=; step>; --step){
if (fa[x][step]!=fa[y][step]){
x=fa[x][step];
y=fa[y][step];
}
}
if (x!=y) x=fa[x][];
return x;
} int main(){
for (int i=; i<maxn; ++i) first1[i]=first2[i]=-;
scanf("%d", &n);
for (int i=; i<=n; ++i){
int t;
scanf("%d", &t);
while (t) {
addedge(first1, edges1, cnte1, , i, t);
addedge(first2, edges2, cnte2, , t, i);
++out[i];
scanf("%d", &t);
}
}
queue<int> q;
for (int i=; i<=n; ++i){
if (!out[i]){
addedge(first1, edges1, cnte1, , i, );
addedge(first2, edges2, cnte2, , , i);
out[i]=;
}
}
//以上:读入、加边
q.push();
int nownode, nowedge, nowson;
for (int i=; i<=n; ++i){
nownode=q.front();
q.pop();
topo[i]=nownode;
nowedge=first2[nownode];
while (nowedge!=-){
nowson=edges2[nowedge].to;
if (!--out[nowson]){
q.push(nowson);
}
nowedge=edges2[nowedge].next;
}
}
//以上:拓扑排序
int lca=, cur=;
for (int i=; i<=n; ++i){
nownode=topo[i];
nowedge=first1[nownode];
lca=nowson=edges1[nowedge].to;
nowedge=edges1[nowedge].next;
while (nowedge!=-){
nowson=edges1[nowedge].to;
//if (!nowedge) break; !!!!
lca=get_lca(lca, nowson);
nowedge=edges1[nowedge].next;
}
dep[nownode]=dep[lca]+;
cur=;
fa[nownode][cur]=nownode;
fa[nownode][++cur]=lca;
++size[lca];
while (fa[nownode][cur]){
fa[nownode][cur+]=fa[fa[nownode][cur]][cur];
++cur;
}
}
//以上:建立灭绝树
while (!q.empty()) q.pop();
for (int i=; i<=n; ++i){
ans[i]=;
if (size[i]==) q.push(i);
}
int fath;
for (int i=n; i>; --i){
nownode=q.front();
q.pop();
fath=fa[nownode][];
--size[fath];
if (!size[fath]) q.push(fath);
ans[fath]+=ans[nownode];
}
//以上:统计size
for (int i=; i<=n; ++i)
printf("%d\n", ans[i]-);
return ;
}

附:用来对拍的python程序。

 from cyaron import *
from random import randint for n in range(5, 11):
input_io = IO()
for i in range(0, 100):
#对于n,生成100个数据。
input_io.input_writeln(n)
print(n) ###
topo = Vector.random(n, [(1, n)], 0)
for j in topo:
print(j, end=' ') ###
#拓扑序
print() ###
m = randint(n*2, n*3)
#有多少个边(有一些边会被舍弃掉)
out = []
for j in range(0, n):
out.append(0)
#每个结点的出度(吃什么)
for j in range(0, m):
t = randint(0, n-1)
if out[t] < t / 2:
out[t] += 1
graph = []
for j in range(0, n):
graph.append([])
for j in range(1, n):
#对于每一个结点
use = []
#连了哪些结点
for k in range(0, n):
use.append(0)
for k in range(0, out[j]):
#对于要连的边
node = randint(0, j-1)
while use[node] == 1:
node = randint(0, j-1)
use[node] = 1
#选一个点
graph[topo[j][0]-1].append(topo[node][0])
for j in graph:
for k in j:
#print(k, end=" ")
input_io.input_write(k)
#print(0)
input_io.input_writeln(0)
Compare.program("mine.exe", input=input_io,
std_program="yangs.exe", stop_on_incorrect=True)

倍增lca-ZJOI2012 灾难的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 1321. [ZJOI2012] 灾难

    1321. [ZJOI2012] 灾难 ★★☆   输入文件:catas.in   输出文件:catas.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 阿米巴是小强的 ...

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

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

  8. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  9. 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

  10. Gym100685G Gadget Hackwrench(倍增LCA)

    题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...

随机推荐

  1. ES doc_values介绍2——本质是field value的列存储,做聚合分析用,ES默认开启,会占用存储空间

    一.doc_values介绍 doc values是一个我们再三重复的重要话题了,你是否意识到一些东西呢? 搜索时,我们需要一个“词”到“文档”列表的映射 排序时,我们需要一个“文档”到“词“列表的映 ...

  2. 5 Python 数据类型—数字

    Python Number 数据类型用于存储数值. 数据类型是不允许改变的,这就意味着如果改变 Number 数据类型的值,将重新分配内存空间. var1 = 1 var2 = 10 您也可以使用de ...

  3. 属性成员是isXxx时对应的get方式是isXxx,前台jsp取不到这个属性值

    最近在项目中无意设置的boolean变量值为isXxx,用eclipse生成相应的set和get方法,eclipse生成的的boolean类型的get方法为isXxx,前台导致取不到相应的值 publ ...

  4. php断点续传

    http://www.cnblogs.com/xproer/archive/2012/10/26/2741264.html

  5. HDU3579Hello Kiki(中国剩余定理)(不互质的情况)

    One day I was shopping in the supermarket. There was a cashier counting coins seriously when a littl ...

  6. ACM学习历程——ZOJ 3829 Known Notation (2014牡丹江区域赛K题)(策略,栈)

    Description Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathema ...

  7. oracle 12c 多租户 pdb 恢复(单个pdb数据文件、非系统pdb表空间、整个pdb数据库)

    环境:数据库版本 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 实验准备:1.-- 数据库归 ...

  8. BZOJ5289:[HNOI2018]排列

    我对贪心的理解:https://www.cnblogs.com/AKMer/p/9776293.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem ...

  9. vijos1779国王游戏

    描述 恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这n位大臣排成一排,国王站在队伍的最前面.排好队后, ...

  10. Python:Iterable和Iterator

    转于:https://blog.csdn.net/whgqgq/article/details/63685066 博主:gongqi1992 iterable和iterator最基本的区别: iter ...