传送门

学LCA的时候根本没意识到LCA可以有这么多玩法。

这玩意据说是个高级数据结构(支配树)的弱化版,蒟蒻没学过呀。所以出题人提出一个概念叫灾难树。


我理解的灾难树的意思实际上是属于DAG的一个子图(我不知道怎么描述,就叫子图吧!)。灾难树关于DAG有这样一个性质。就是说在DAG上删掉某一点后,如果存在一个点的入度变为0.那么这个点就删去,以此类推,而被删去的点是这个所有被迫删除的点的父亲。

上面实际上就是把题面描述了一遍QAQ。

如何根据原DAG构建灾难树呢?

首先把DAG拓扑排个序。然后逆序遍历,对于拓扑序上的每一个点。找到他所有子节点在新图上的LCA(如果不存在或者LCA就是该节点就设为0)。然后就在新图上由LCA向这个点连边。最后形成的新图就是灾难树。

其实如果偏感性的理解的话,就是如果一个点所有出边所连接的点,或者通俗点说,就是所有食物都没了,那么这个点是一定要随之被删掉的。也就是说LCA的被删去必定会导致当前节点的被删去。

//BZOJ 2815
//by Cydiater
//2016.10.21
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int N,LINK[MAXN],len=0,indu[MAXN],head,tail,q[MAXN],Link[MAXN],LEN=0,fa[MAXN][21],dep[MAXN],siz[MAXN];
struct edge{
	int y,next;
}e[MAXN],E[MAXN];
namespace solution{
	inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;}
	inline void Insert(int x,int y){E[++LEN].next=Link[x];Link[x]=LEN;E[LEN].y=y;}
	void init(){
		N=read();
		memset(indu,0,sizeof(indu));
		up(i,1,N){
			int y=read();
			while(y){insert(i,y);indu[y]++;y=read();}
		}
	}
	int LCA(int x,int y){
		if(x==-1)return y;
		if(dep[x]<dep[y])swap(x,y);
		down(i,20,0)if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];
		if(x==y)		return x;
		down(i,20,0)if(fa[x][i]!=fa[y][i]&&fa[x][i]!=0){
			x=fa[x][i];
			y=fa[y][i];
		}
		return fa[x][0];
	}
	void get_ancestor(int node){
		up(i,1,20)if(fa[node][i-1]!=0)fa[node][i]=fa[fa[node][i-1]][i-1];
	}
	void dfs(int node){
		siz[node]=1;
		for(int i=Link[node];i;i=E[i].next){
			dfs(E[i].y);
			siz[node]+=siz[E[i].y];
		}
	}
	void slove(){
		head=1;tail=0;up(i,1,N)if(!indu[i])q[++tail]=i;
		for(;head<=tail;head++){
			int node=q[head];
			for(int i=LINK[node];i;i=e[i].next)
				if(--indu[e[i].y]==0)q[++tail]=e[i].y;
		}
		down(h,tail,1){
			int node=q[h],lca=-1;
			for(int i=LINK[node];i;i=e[i].next)lca=LCA(lca,e[i].y);
			if(lca==node||lca==-1)lca=0;
			Insert(lca,node);fa[node][0]=lca;dep[node]=dep[lca]+1;
			get_ancestor(node);
		}
		memset(siz,0,sizeof(siz));
		dfs(0);
	}
	void output(){
		up(i,1,N)printf("%d\n",siz[i]-1);
	}
}
int main(){
	//freopen("input.in","r",stdin);
	using namespace solution;
	init();
	slove();
	output();
	return 0;
}

BZOJ2815: [ZJOI2012]灾难的更多相关文章

  1. BZOJ2815:[ZJOI2012]灾难(拓扑排序,LCA)

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

  2. [BZOJ2815][ZJOI2012]灾难(拓扑排序/支配树)

    支配树目前只见到这一个应用,那就不独分一类,直接作为拓扑排序题好了. 每个点向所有食物连边,定义fa[x]为x的支配点,即离x最近的点,满足若fa[x]灭绝,则x也要灭绝. 这样,将fa[x]向x连边 ...

  3. [BZOJ2815][ZJOI2012]灾难 灭绝树+拓扑排序+lca

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

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

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

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

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

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

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

  7. 1321. [ZJOI2012] 灾难

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

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

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

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

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

随机推荐

  1. CREATE FILE encountered operating system error 5(Access is denied.)

    这篇博文主要演示"CREATE FILE encountered operating system error 5(Access is denied.)"错误如出现的原因(当然只是 ...

  2. IP 地址分类(A、B、C、D、E类)

    互联网上的接口的唯一地址. IP 32位的地址通常表示为四个10进制的数,每个证书对应一个字节,成为点分十进制法(Dotted decimal notation) 如上图首字节整数:A类--0开始,B ...

  3. IIS不能下载ini文件

    1.打开IIS. 2.选择站点或者存放*.ini文件的目录,右键菜单中选择属性. 3.选择“HTTP头”选项卡. 4.点击“MINE类型”. 5.点击“新建”. 6.这是跳出一个对话框,在“扩展名”一 ...

  4. .NET应用程序调试—原理、工具、方法

    阅读目录: 1.背景介绍 2.基本原理(Windows调试工具箱..NET调试扩展SOS.DLL.SOSEX.DLL) 2.1.Windows调试工具箱 2.2..NET调试扩展包,SOS.DLL.S ...

  5. python MySQLdb 对mysql基本操作方法

    #!/usr/bin/env python # -*- coding:utf-8 -*- import MySQLdb conn = MySQLdb.connect(host=',db='host') ...

  6. linux 之静默安装oracle

    Web服务器上面的Linux一般是不会有图形界面的,所有通过图形界面来安装Linux的方式在没有图形界面的Linux上面是行不通的,我们要使用的安装方式叫做Linux的静默安装.即在没有图形界面的Li ...

  7. 4412开发板搭建Uboot、Kernel和Android4.0的编译环境方法

    本文转自迅为4412开发板实战教程书籍:http://www.topeetboard.com 迅为是基于Ubuntu12.04.2平台做开发,所有的配置和编译脚本也是基于此平台,没有在其它平台上测试过 ...

  8. AngularJS笔记---作用域和控制器

    什么是作用域. 什么是控制器, 作用域包含了渲染视图时所需的功能和数据,它是所有视图的唯一源头.可以将作用域理解成试图模型(ViewModel). 作用域之间可以是包含关系也可以是独立关系.可以通过设 ...

  9. 【2016-11-15】【坚持学习】【Day26】【WPF 命令绑定到事件】

    今天同事跟我说了已经有用的东西. System.Windows.Interativity 这个命名空间可以让我在界面上将命令绑定到对应的事件上.解决了我一直的疑问,只有点击事件可以绑定??现在有答案了 ...

  10. NOI2001|POJ1182食物链[种类并查集 向量]

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65430   Accepted: 19283 Description ...