bzoj2815: [ZJOI2012]灾难
话说这个就是灭绝树/支配树?感觉就是LCA的思路题嘛。
对于一个生物,它死只有它的所有食物死,然而我们询问的是死一个多少死
我们可以建出一棵树,父亲连向子节点当且仅当父亲死了孩子必死,而且是距离最近的
这是一个有向无环图,我们可以让生产者向消费者连边,进行拓扑排序
当拓扑到当前点的时候,它的食物就已经在树里面了,而当前点死最近的方法就是它所以食物的LCA死
那么就这样建边
答案就是子树大小-1
囧LCA写错WA一发
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> using namespace std; struct node{int x,y,next;}; node e[110000];int elen,elast[110000]; void eins(int x,int y) { elen++; e[elen].x=x;e[elen].y=y; e[elen].next=elast[x];elast[x]=elen; } int Bin[30],f[30][110000],dep[110000]; int cc; void add(int x,int F) { eins(F,x);dep[x]=dep[F]+1; f[0][x]=F;cc++; for(int i=1;Bin[i]<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]]; } int LCA(int x,int y) { if(x==-1)return y; if(dep[x]<dep[y])swap(x,y); for(int i=25;i>=0;i--) if(dep[x]-dep[y]>=Bin[i])x=f[i][x]; if(x==y)return x; for(int i=25;i>=0;i--) if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y]; return f[0][x]; } //--------------------------------------------------------------------------------------------------------------------------------- node a[2100000];int len,last[110000],du[110000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } vector<int>vec[110000]; int getfa(int x) { if(x==23) { int t;t++; } int ret=-1; for(int i=0;i<vec[x].size();i++) ret=LCA(ret,vec[x][i]); //if(ret==-1)ret=0; return ret; } int top,sta[110000]; void topsort(int n) { for(int i=1;i<=n;i++) if(du[i]==0)sta[++top]=i,add(i,0); while(top!=0) { int x=sta[top];top--; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; du[y]--; if(du[y]==0) sta[++top]=y,add(y,getfa(y)); } } } //--------------------------------------------------------------------------------------------------------------------------------- int tot[110000]; void dfs(int x) { tot[x]=1; for(int k=elast[x];k;k=e[k].next) { int y=e[k].y; dfs(y); tot[x]+=tot[y]; } } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n,x; scanf("%d",&n); len=0; for(int i=1;i<=n;i++) { while(scanf("%d",&x)!=EOF) { if(x==0)break; ins(x,i);du[i]++; vec[i].push_back(x); } } elen=0; Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2; memset(f[0],-1,sizeof(f[0]));cc=0; topsort(n); dfs(0); for(int i=1;i<=n;i++) printf("%d\n",tot[i]-1); return 0; }
pain and happy in the cruel world.