Logu P2597 [ZJOI2012] Disaster (Dominant Tree/Pass-through Point)

Links: https://www.luogu.org/problem/P2597

Topic: Give you an n for n species of organisms.Next n rows give the species that biology I can eat, each ending with 0.For each organism i, if it goes extinct, find out how many species will also go extinct because there is no food.

THINK: The title statement is DAG (directed acyclic graph), so the title is obviously a simple dominant tree (about the mandatory points).Create a super source point 0 (which you can think of as the sun), and if it's gone, all species will be extinct, which means he's a must-have for all species, corresponding to the title, where the disaster value of 0 is n.The title is DAG, but there is no guarantee that the map will be connected, that is, it may be a forest.That's why point zero was introduced, so we've given the point zero (corresponding to the producer described in the title), which guarantees that the graph is a tree.Obviously producers are a must-have for most organisms (that is, if it goes extinct, many will follow).When we draw, set the direction of the edge to have the eater point at the eatee.By the nature of the dominant tree, all ancestors who dominate a point in the tree are its necessary points.Because of the way we build the map, the points sorted by the topology will surely drain backwards and be closer to the root node in the dominant tree.Then by the nature of the dominant tree, for this topic, assuming that a point is u, the point set V that he points to must already be in the dominant tree, and calculating the LCA of all points in the point set V in the dominant tree (assuming w), then w is the father of u in the dominant tree.Depending on this nature, combined with the way we plot, we add points to the dominant tree in a topologically ordered order upside down, and finally each point is answered by a size of -1 (not including itself) of the subtree in the dominant tree.(For biological i, the answer is the number of organisms that must pass through biological i.)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 7e4+10;
int deep[N],f[N][20],in[N],id[N],q[N],he,ta;
int n,root,x,num,u,v,ans[N];
vector<int> g[N],trg[N];
void TopoSort()
{
	num=0;
	he=ta=0;
 	for(int i=1;i<=n;i++)
 		if(!in[i]) q[ta++]=i;
	while(he!=ta)
	{
		u=q[he++];
		id[++num]=u;
		for(int i=0;i<g[u].size();i++)
		{
			v=g[u][i];
			in[v]--;
			if(!in[v])
			{
				q[ta++]=v;
			}
		}
	}
	return;
}
int Lca(int x,int y)
{
	if(deep[x]<deep[y])
		swap(x,y);
	int diff=deep[x]-deep[y];
	for(int i=17;i>=0;i--)
		if(diff&(1<<i)) x=f[x][i];
	if(x==y) return x;
	for(int i=17;i>=0;i--)
		if(f[x][i]!=f[y][i])
			x=f[x][i],y=f[y][i];
	return f[x][0];
}
void dfs(int u)
{
	//cout<<u<<endl;
	ans[u]=1;
	for(int i=0;i<trg[u].size();i++)
	{
		dfs(trg[u][i]);
		ans[u]+=ans[trg[u][i]];
	}
	return ;
}
int main(void)
{
	//cout<<(1<<16)<<endl;
	//freopen("catas.in","r",stdin);
	//freopen("catas.out","w",stdout);
	//Title description file read in and read out, actually not used, mother's scare. 
	root=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		num=0;
		while(~scanf("%d",&x)&&x)
		{
			g[i].push_back(x);
			in[x]++;
			num++;
		}
		if(!num) 	
		{
			//i is the producer, connecting it to the sun (0) 
			//Join Dominant Tree 
			trg[root].push_back(i);
		}	
	}
	TopoSort();
	//Inverse Topology Ordering Mapping 
	for(int i=n;i>=1;i--)
	{
		
		v=id[i];
		//v is a producer and has been added to the dominant tree.
		//No need to add 
		if(!g[v].size()) continue;
		u=g[v][0]; 
		//Requirements by nature 
		for(int j=1;j<g[v].size();j++)
			u=Lca(u,g[v][j]);
		//cout<<v<<" "<<u<<endl;	
		trg[u].push_back(v);
		deep[v]=deep[u]+1;
		f[v][0]=u;
		for(int i=1;i<=17;i++)
			f[v][i]=f[f[v][i-1]][i-1];
	}
	dfs(root);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]-1);
	return 0;
}

 

Posted by rostros on Tue, 30 Jul 2019 13:08:44 -0700