Description

阿米巴是小强的好朋友。

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

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

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

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

这个图没有环。

图中有一些点没有连出边,这些点代表的生物都是生产者,可以通过光合作用来生存; 而有连出边的点代表的都是消费者,它们必须通过吃其他生物来生存。

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

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

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

如果小强和阿米巴把草原上所有的羊都给吓死了,那么狼会因为没有食物而灭绝,而小强和阿米巴可以通过吃牛、牛可以通过吃草来生存下去。所以,羊的灾难值是1。但是,如果草突然灭绝,那么整个草原上的5种生物都无法幸免,所以,草的灾难值是4。

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

Input

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

接下来 N 行,每行描述了一个生物可以吃的其他生物的列表,格式为用空格隔开的若干个数字,每个数字表示一种生物的标号,最后一个数字是 0 表示列表的结束。

Output

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

Sample Input

5
0
1 0
1 0
2 3 0
2 0

Sample Output

4
1
0
0
0

Hint

【样例说明】

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

【数据规模】

对50%的数据,N ≤ 10000。

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

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

题解

拓扑排序+倍增$LCA$

暴力的n2算法肯定是不行的,我们需要考虑特殊的做法。

由于每次有且只有一种生物灭绝,而当且仅当x的所有食物都灭绝,$x$才会灭绝。

所以所有$x$的食物从上至下能共同达到的某个节点灭绝时,$x$才会灭绝。

根据这个我们可以重构树然后跑$LCA$。

先把所有没有食物的点(题目中描述为“生产者”)向$0$连一条边。

然后对原图进行拓扑排序,得到每个点进队列的顺序。

再从后向前扫一遍,对于每个点,对它的所有食物节点求一下$LCA$(两两求一次),将这个点连到$LCA$上。

由于我们加了“生产者”$->0$的一条边,所以能够使得加进来的是一棵树,而不是一个森林。

每次重构时,不需要$LCT$,直接看作新加一个节点$x$,$f[x][0]=LCA$,然后处理一下就行了。

最后要求的就是子树大小$-1$,所以利用拓扑排序(也就是一种$bfs$序)向上更新即可。

举样例的例子:

我们容易发现草的灾难值为$4$,羊的灾难值为$1$。

$Ps$:听说这东西叫灭绝树,还以为是什么奇怪的数据结构,就是拓扑排序+倍增$LCA$。估计这就是母题了吧?

神犇的注解:

    我们需要构造一棵“灭绝树”。
“灭绝树”满足以下性质:对于一棵多叉树的任意一个结点,当它“灭绝”时,它所有的后代也会跟着“灭绝”。
再回过来看这道题,题目要求的是某种生物“灭绝”后跟着“灭绝”的其他生物的数量,即这种生物在“灭绝树”中的后代数量。
那么问题来了,怎么建立“灭绝树”?
很显然,一种生物会“灭绝”只有两种情况:一是它原本就“灭绝”(即我们要求灾难值的那种生物),二是它所有的食物都“灭绝”。
第一种情况不用考虑,那么我们来考虑第二种情况。
假设有生物I。很显然,只有当生物I的所有食物的最近公共祖先(LCA)J“灭绝”时,生物I的所有食物才会同时“灭绝”(显然这里就要用到倍增求LCA的算法),然后,我们将生物I作为生物J的一个新的孩子节点,表示当J“灭绝”时,I也会跟着“灭绝”(因为它所有的食物都“灭绝”了)。
根据题目需求,最后只要输出每种生物在“灭绝树”中的所有后代数量(数量的计算可以在每次“灭绝树”加入新节点时进行一次DFS)就可以了。
 #include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define RE register
#define IL inline
using namespace std;
const int N=;
const int M=; int n,x,op;
struct tt
{
int to,next;
}edge[M+];
int path[N+],top;
IL void Add(int u,int v); int in[N+];
int size[N+]; int q[N+],head,tail;
IL void Topsort(); int deep[N+],fa[N+][];
IL int LCA(int x,int y); int main()
{
scanf("%d",&n);
op=log2(n);
for (RE int i=;i<=n;i++)
{
scanf("%d",&x);
if (!x) Add(i,);
while (x)
{
Add(i,x);
in[x]++;
scanf("%d",&x);
}
}
Topsort();
for (RE int i=n;i>=;i--)
{
int u=q[i],t=edge[path[u]].to;
for (RE int j=edge[path[u]].next;j;j=edge[j].next) t=LCA(t,edge[j].to);
fa[u][]=t;
deep[u]=deep[t]+;
for (RE int t=;t<=op;t++) fa[u][t]=fa[fa[u][t-]][t-];
}
for (RE int i=;i<=n;i++) size[q[i]]++,size[fa[q[i]][]]+=size[q[i]];
for (RE int i=;i<=n;i++) printf("%d\n",size[i]-);
return ;
} IL void Topsort()
{
head=tail=;
for (RE int i=;i<=n;i++) if (!in[i]) q[tail++]=i;
while (head<tail)
{
int u=q[head++];
for (RE int i=path[u];i;i=edge[i].next)
{
in[edge[i].to]--;
if (!in[edge[i].to]) q[tail++]=edge[i].to;
}
}
}
IL void Add(int u,int v)
{
edge[++top].to=v;
edge[top].next=path[u];
path[u]=top;
}
IL int LCA(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
for (RE int i=op;i>=;i--) if (deep[fa[x][i]]>=deep[y]) x=fa[x][i];
if (x==y) return x;
for (RE int i=op;i>=;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][];
}

[ZJOI 2012]灾难的更多相关文章

  1. 数学 ZJOI 2012 数列

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; ; st ...

  2. [ZJOI 2012] 网络

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2816 [算法] 对每种颜色的边建一棵LCT , 维护联通性即可 时间复杂度 : O( ...

  3. SQL Server 2012 AlwaysOn集群配置指南

    1. AlwaysOn介绍 AlwaysOn是SQL Server 2012提供的全新综合.灵活.高效经济的高可用性和灾难恢复解决方案.它整合了镜像和群集的功能,基于OS 故障转移群集(Windows ...

  4. 桦仔 笔记4-徐 模仿灾难发生时还原adventurework数据库 示例 stopat

    1 --模仿灾难发生时还原adventurework数据库 示例 stopat 2 3 BACKUP DATABASE AdventureWorks 4 TO DISK= 'D:\MSSQL\Data ...

  5. windows server 2012 AD 活动目录部署系列(五)备份和还原域控制器

    在前篇博文中,我们介绍了用户资源的权限分配,用户只要在登录时输入一次口令,就能访问基于该域所分配给他的所有资源. 但是我们需要考虑一个问题:万一域控制器坏了怎么办?!如果这个域控制器损坏了,那用户登录 ...

  6. SQL Server中灾难时备份结尾日志(Tail of log)的两种方法

    转自:http://www.cnblogs.com/CareySon/archive/2012/02/23/2365006.html SQL Server中灾难时备份结尾日志(Tail of log) ...

  7. 摩根大通银行被黑客攻克, ATM机/网银危在旦夕,winxp退市灾难来临了

    winxp4月退市到如今还不到半年,就出现故障了 7600多万个消费者银行账户被黑.此外还有700万个小企业账户的信息也被黑客窃取,这个算不算灾难呢?假设等到银行业彻底崩溃,资金彻底丧失,那不仅仅是灾 ...

  8. Windows server 2012 添加中文语言包(英文转为中文)(离线)

    Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...

  9. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

随机推荐

  1. 简单hdfs相关操作命令

    HDFS常用操作命令 启动hdfs #start-all.sh 查看hdfs的配置文件 #cat hdfs-site.sh #hadoop fs -put /soft/jdk / #HDFS上传文件命 ...

  2. Alpha冲刺——Day1

    一.合照 二.项目燃尽图 三.项目进展 1.界面设计:图形界面部分完成 2.数据库设计:数据库设计基本完成 3.搭建基本服务器框架 github链接 四.明日规划 1.继续完成剩下的图形界面 2.An ...

  3. Beta总结篇

    45°炸 031502601 蔡鸿杰 031502604 陈甘霖 031502632 伍晨薇 一.项目预期进展及现实进展 项目预期计划 现实进展 Github使用 √ 日拍 (调用相机.相册) √ 足 ...

  4. tornado httpserver

    # coding:utf-8 import tornado.web import tornado.ioloop import tornado.httpserver # 新引入httpserver模块 ...

  5. nyoj 复杂度

    复杂度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) for(k=j+1;k ...

  6. php的打印sql语句的方法

    echo M()->_sql(); 这样就可以调试当前生成的sql语句: //获取指定天的开始时间和结束时间 $datez="2016-05-12"; $t = strtot ...

  7. ASP.NET 访问项目网站以外的目录文件

    简单的说,可以通过在 IIS 添加虚拟目录的方法做到,获取访问路径的时候就用 HttpContext.Current.Server.MapPath("~/xxx"); 的方式. 下 ...

  8. C语言头文件引用

    1,引用分为两种 firs:include<fileName.h> 引用系统头文件一般用<>. second:include"fileName.h" 引用自 ...

  9. 分贝块---dBblock

    分贝,用英语来表达的话,是decibel,是量度两个相同单位之数量比例的计量单位,主要用于度量声音强度,常用dB表示. 块,block,在百度百科中,指数据库中的最小存储和处理单位,包含块本身的头信息 ...

  10. 【笔记】HybridApp中使用Promise化的JS-Bridge

    背景: HybridApp,前端采用JS-bridge的方式调用Native的接口,如获取设备信息.拍照.人脸识别等 前端封装了调用库,每次调用Native接口,需要进行两步操作(1.在window下 ...