最近想学支配树,但是基础还是要打好了的;

P2597 [ZJOI2012]灾难

这道题是根据食物链链接出一个有向图的关系,求一个物种的灭绝会连带几种物种的灭绝;

求得就是一个点能支配几个点;

如果一个点没有食物了就会灭绝,那他的支配点就是他所有食物的LCA;

LCA死了,食物都死了,他也就死了;

我们先根据吃和被吃建图,连一条他和食物的有向边;

我们处理出拓扑序,入度为零的点就是终极捕食者;

重新建一个树,每个点支配的数量就是他为根的子树大小-1;

我们只需要将他和食物的LCA连边即可;这个时候我们连接的是反的,食物连向捕食者,这样子树大小才正确;

新加的虚拟节点没有影响,遍历树时很方便。

建立编号n+1的虚拟节点,将所有没有出边的光合食物连向这个点,以便以后求LCA;

注意每次都要更新f[][];

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=7e5+;
int pre[maxn*],last[maxn],other[maxn*],l;
int pre2[maxn*],last2[maxn],other2[maxn*],l2;
int n;
void add(int x,int y)
{
l++;
pre[l]=last[x];
last[x]=l;
other[l]=y;
} void add2(int x,int y)
{
l2++;
pre2[l2]=last2[x];
last2[x]=l2;
other2[l2]=y;
}
queue<int> q;
int topo[maxn],sum,in_eage[maxn];
int dep[maxn],father[maxn]; int f[maxn][]; void rmq(int x)
{
f[x][]=father[x];
for(int i=;i<=;i++)
{
f[x][i]=f[f[x][i-]][i-];
}
} int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=;i<=;i++)
{
if((dep[x]-dep[y])&(<<i)) x=f[x][i];
}
if(x==y) return x;
for(int j=;j>=;j--)
{
if(f[x][j]!=f[y][j])
{
x=f[x][j];
y=f[y][j];
}
}
return f[x][];
} void toposort()
{
for(int i=;i<=n;i++)
{
if(in_eage[i]==)
{
q.push(i);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
topo[++sum]=x;
for(int p=last[x];p;p=pre[p])
{
int v=other[p];
in_eage[v]--;
if(in_eage[v]==)
{
q.push(v);
}
}
}
} void build()
{
dep[n+]=;
father[n+]=n+;
for(int i=n;i>=;i--)
{
int x=topo[i];
if(last[x]==)
{
dep[x]=;
father[x]=n+;
add2(n+,x);
f[x][]=n+;
continue;
}
else
{
int lca=other[last[x]];
for(int p=last[x];p;p=pre[p])
{
int v=other[p];
lca=LCA(lca,v);
}
father[x]=lca;
add2(lca,x);
dep[x]=dep[lca]+;
rmq(x);
}
}
}
int siz[maxn]; void dfs(int x)
{
siz[x]=;
for(int p=last2[x];p;p=pre2[p])
{
int v=other2[p];
dfs(v);
siz[x]+=siz[v];
}
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
while(x)
{
in_eage[x]++;
add(i,x);
scanf("%d",&x);
}
}
toposort();
build();
dfs(n+);
for(int i=;i<=n;i++)
{
printf("%d\n",siz[i]-);
}
return ;
}

P2597 [ZJOI2012]灾难——拓扑,倍增,LCA的更多相关文章

  1. P2597 [ZJOI2012]灾难(倍增LCA+拓扑排序)

    传送门 据大佬说这玩意儿好像叫灾难树还是灭绝树? 我们先按建图,设点$u$的食物有$x[1]...x[k]$,即在图中这些点都有一条指向它的边 以样例来说,对于人,羊和牛都有一条指向它的边,然而不管是 ...

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

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

  3. 洛谷P2597 [ZJOI2012] 灾难 [拓扑排序,LCA]

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

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

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

  5. P2597 [ZJOI2012]灾难 拓扑排序

    这个题有点意思,正常写法肯定会T,然后需要优化.先用拓扑排序重构一遍树,然后进行一个非常神奇的操作:把每个点放在他的食物的lca上,然后计算的时候直接dfs全加上就行了.为什么呢,因为假如你的食物的l ...

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

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

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

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

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

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

  9. BZOJ 2815: [ZJOI2012]灾难 拓扑排序+倍增LCA

    这种问题的转化方式挺巧妙的. Code: #include <bits/stdc++.h> #define N 100000 #define M 1000000 #define setIO ...

随机推荐

  1. 用ASP.NET Web API技术开发HTTP接口(一)

    开发工具 Visual Studio 2013 SQL Server 2008 R2 准备工作 启动Visual Studio 2013,新建一个ASP.NET Web应用程序,命名为SimpleAP ...

  2. 【转载】Intellij IDEA神器居然还有这些小技巧

    概述Intellij IDEA真是越用越觉得它强大,它总是在我们写代码的时候,不时给我们来个小惊喜.出于对Intellij IDEA的喜爱,我决定写一个与其相关的专栏或者系列,把一些好用的Intell ...

  3. vue基础部分

    一 vue概念 是一个构建用户界面的javascript框架 二 如何使用vue 1. 导入vue.js文件 2. 展示HTML 3. 建立vue对象,写JavaScript代码 vue的简单实用:申 ...

  4. 关于Vue-ElementUI修改默认样式不成功问题解决

    Element是一个很好用的组件库,但是有时候我们需要修改一些组件的样式以满足我们自己的需求. 我们用浏览器调试找到相应的class,在本地重写这个class时,发现修改不成功. 这是因为在Vue文件 ...

  5. js循环修改数组属性key值

    var keyMap = { deviceUid: "id", deviceType: "typeName", deviceCode: "code&q ...

  6. STM8 LED

    时钟分频寄存器(CLK_CKDIVR) 举例 int main() { CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //高速内部时钟1分频 GPIO_ ...

  7. 流程控制 while for

    循环执行 计算机最擅长的功能之一就是按照规定的条件,重复执行某些操作,这是程序设计中最能发挥计算机特长的程序结构. 1.while语句 while(表达式){ 各种语句.... } 当表达式的值为tr ...

  8. JAVA笔记整理(一),JAVA介绍

    JAVA语言的版本: J2SE(Java2 Platform Standard Edition,java平台标准版),后更名为:JAVA SE J2EE(Java 2 Platform,Enterpr ...

  9. 极度舒适的 Python 入门教程,小猪佩奇也能学会~

    编程几乎已经成为现代人的一门必修课,特别是 Python ,不仅长期霸占编程趋势榜.薪资榜第一,还屡屡进入小学教材,甚至成为浙江省信息技术高考项目-- 今天,小编带来了一门极度舒适的 Python 入 ...

  10. C++——异常处理

    前言 大型和十分复杂的程序往往会产生一些很难查找的甚至是无法避免的运行时错误.当发生运行时错误时,不能简单地结束程序运行,而是退回到任务的起点,指出错误,并由用户决定下一步工作.面向对象的异常处理(e ...