倍增lca-ZJOI2012 灾难
一个食物网有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 灾难的更多相关文章
- Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造
Luogu_2597_[ZJOI2012]灾难 倍增lca + 构造 题意: 我们用一种叫做食物网的有向图来描述生物之间的关系:一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连 ...
- 【bzoj2815】[ZJOI2012]灾难 拓扑排序+倍增LCA
题目描述(转自洛谷) 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过生物 ...
- P2597 [ZJOI2012]灾难——拓扑,倍增,LCA
最近想学支配树,但是基础还是要打好了的: P2597 [ZJOI2012]灾难 这道题是根据食物链链接出一个有向图的关系,求一个物种的灭绝会连带几种物种的灭绝: 求得就是一个点能支配几个点: 如果一个 ...
- 【BZOJ2815】[ZJOI2012]灾难 拓扑排序+LCA
[BZOJ2815][ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从 ...
- [洛谷P2597] [ZJOI2012]灾难
洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...
- 1321. [ZJOI2012] 灾难
1321. [ZJOI2012] 灾难 ★★☆ 输入文件:catas.in 输出文件:catas.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 阿米巴是小强的 ...
- 洛谷 P2597 [ZJOI2012]灾难 解题报告
P2597 [ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发 ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- Gym100685G Gadget Hackwrench(倍增LCA)
题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...
随机推荐
- 关于输出用%lf和%f的问题
关于输入,float用%f,double用%lf 而输出时,无论是float还是double,都用%f 原文请见:http://poj.org/showmessage?message_id=12692 ...
- poj-2420 A Star not a Tree?(模拟退火算法)
题目链接: A Star not a Tree? Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5219 Accepte ...
- stl_iterator.h
stl_iterator.h // Filename: stl_iterator.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: ...
- Java 时间和日期类型的 Hibernate 映射
以下情况下必须显式指定 Hibernate 映射类型 一个 Java 类型可能对应多个 Hibernate 映射类型. 例如: 如果持久化类的属性为 java.util.Date 类型, 对应的 Hi ...
- 输入框input内容变化与onpropertychange事件的兼容
一.输入框常用的几个事件 onblur 元素失去焦点. onchange 域的内容被改变. onclick 当用户点击某个对象时调用的事件句柄. ondblclick 当用户双击某个对象时调用的事件句 ...
- POJ1442:Black Box
浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=1442 用对顶堆维护第\(k\)小 ...
- 【转】 Pro Android学习笔记(四十):Fragment(5):适应不同屏幕或排版
目录(?)[-] 设置横排和竖排的不同排版风格 改写代码 对于fragment,经常涉及不同屏幕尺寸和不同的排版风格.我们在基础小例子上做一下改动,在横排的时候,仍是现实左右两个fragment,在竖 ...
- bean validator - Hibernate validator
在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间.成本.质 ...
- RS485总线防雷保护方案
RS485作为最为最常用的电表通讯方式之一.日常生活中雷电和静电干扰已经成为485通信总线在实际工程经常遇到的问题.故如何对芯片以及总线进行有效的保护,是摆在每一个使用者面前的一个问题.在这里,我们主 ...
- Packet for query is too large
数据库:mysql5.6 framework: play framework 1.2.4 近日处理批量数据的insert,update,涉及的保存更新sql大概有18w.我的操作如下: 1)每次取10 ...