倍增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步经过边的 ...
随机推荐
- 大白话AOP
工作一年多后, 第二次看了韩顺平老师讲的AOP (11年的Spring 教学视频) AOP还是比较艰涩的东西. 从刚开始 碰Java项目去找书看开始, 到学了拦截器知道AOP就是处理事务, 日志, 安 ...
- C/C++ 安全编码 —— 不安全的函数
1. 文件与IO操作 gets():从控制台输入到字符数组: char response[8]; gets(response); 如果控制台输入超过 8 个字符,程序便会发生不确定的行为.其主要问题在 ...
- Android repo 学习参考
/*************************************************************************** * Android repo 学习参考 * 说 ...
- centos6.6系统初始化脚本
#!/bin/bash # Program: # system_init_shell # History: # 2012/06/01 25061008@qq.com # Release: # 1.1 ...
- UE3代码阅读需知
转自:http://www.cnblogs.com/hmxp8/archive/2012/02/21/2361211.html 掌握一款庞大的引擎,要一下子掌握真的很难,慢慢地从Editor,Scri ...
- centos7 firewalld使用
转 http://blog.csdn.net/jamesge2010/article/details/52449678 1.firewalld的基本使用 启动: systemctl start fir ...
- LAMP 1.2 Apache编译安装问题解决
这个错误安装 yum install -y gcc error: mod_deflate has been requested but can not be built due to prerequi ...
- Qt webview调用JavaScript 带参函数
void MainWindow::on_pushButtonShowMarker_clicked() { QString lat = "104.701681"; QString l ...
- web实现本地缓存的方法
Cookie(或者Cookies) 指一般网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). cookie一般通过http请求中在头部一起发送到服务器端.一条c ...
- RN控件之DrawerLayoutAndroid导航栏
/** * Sample React Native App * https://github.com/facebook/react-native */ 'use strict'; import Rea ...