【ZJOI2012】灾难(拓扑+重新建树+lca)

该博客探讨了如何利用拓扑排序和最近公共祖先(LCA)算法解决ZJOI2012竞赛中的‘灾难’问题。文章指出,当生产者节点死亡时,其子树会受到影响;而消费者只有在其所有食物来源(生产者)都死亡时才会死亡。解决方案包括构建反映这种依赖关系的树,并强调不能简单地按顺序枚举节点以计算LCA,因为这可能导致错误。作者提出要考虑拓扑层次来正确处理问题。
摘要由CSDN通过智能技术生成

(我怎么又双叒叕发烧了...)

不难想到 对于一个生产者 它死了 所有它的子树就都死了

换句话说 对于一个消费者 它死 当且仅当它的所有食物都死了 什么时候所有食物都死了呢?——最顶端的生产者死了。否则,那消费者一定能至少找到一种食物

假如我们能够建出这样的一颗树就是极好的 不妨先来考虑建树的过程 对于新加入的点now 首先我们确定now是否为生产者 否则 将now放在食物们lca的儿子的地方即可

那肯定不能直接1~n枚举 这样找出来的LCA是错的 由于没有环 考虑拓扑先确定层次

#include<bits/stdc++.h>
const int N=65535;
using namespace std;
int n;
int first[N],tot;
struct Edge
{
	int to,next;
}edge[2*N];
inline void addedge(int x,int y)
{
	tot++;
	edge[tot].to=y; edge[tot].next=first[x]; first[x]=tot;
}
int in[N],topo[N],num;
void Topo_sort()
{
	queue <int> q;
	for(int i=1;i<=n;i++)	if(!in[i])	q.push(i);
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		topo[++num]=now;
		for(int u=first[now];u;u=edge[u].next)
		{
			int vis=edge[u].to;
			in[vis]--;
			if(!in[vis]) q.push(vis);
		}
	}
}
vector <int> e[N];
int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值