Loading

浅谈DAG上的支配树

当树也拥有了很强的控制欲……

[ZJOI2012] 灾难

支配树顾名思义,就是一棵树,这棵树上的节点的父亲对儿子起支配作用(家庭地位),如果父节点没了,儿子节点也没了。

对于这道题,我们可以设生物 \(u\)\(v\) 起支配作用,如果 \(u\) 灭绝了,那么 \(v\) 也会灭绝。那这样,题目所求的灾难值就是 \(i\) 在支配树上的子树大小减一(除自己)。

考虑如何建这棵树。

我们先跑一边拓扑,找出拓扑序。然后按照拓扑序倒序找(从生产者开始找),这个节点的支配点就是她所有相连的点的 \(lca\),加边即可。

#include<bits/stdc++.h>
using namespace std;
inline int read(){
  int ans=0,f=1;char ch=getchar();
  while(!isdigit(ch)){if(ch=='-') f=-f;ch=getchar();}
  while(isdigit(ch)){ans=(ans<<3)+(ans<<1)+ch-48;ch=getchar();}
  return ans*f;
}
const int N=1e6+5,INF=2e9;
int n;
int hd1[N],nx1[N],to1[N],tot1,in[N];
void adde1(int u,int v){
  nx1[++tot1]=hd1[u];to1[tot1]=v;hd1[u]=tot1;in[v]++;
}
int hd[N],nx[N],to[N],tot;
void adde(int u,int v){
  nx[++tot]=hd[u];to[tot]=v;hd[u]=tot;
}
int f[N][25],dep[N];
int LCA(int u,int v){
  if(dep[u]<dep[v]) swap(u,v);
  for(int i=20;i>=0;i--) if(dep[f[u][i]]>=dep[v]) u=f[u][i];
  if(u==v) return u;
  for(int i=20;i>=0;i--) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
  return f[u][0];
}
int tpn[N],cnt;
void topu(){
  queue<int> q;
  for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
  while(!q.empty()){
    int u=q.front();q.pop();
    tpn[++cnt]=u;
    for(int i=hd1[u];i;i=nx1[i]){
      int v=to1[i];
      in[v]--;
      if(!in[v]) q.push(v);
    }
  }
}
void build(){
  dep[n+1]=1;
  for(int i=cnt;i;i--){
    int u=tpn[i];
    if(!hd1[u]){
      adde(n+1,u);
      f[u][0]=n+1;
      dep[u]=2;
      continue;
    }
    int lca=to1[hd1[u]];
    for(int i=nx1[hd1[u]];i;i=nx1[i])
      lca=LCA(lca,to1[i]);
    f[u][0]=lca;
    dep[u]=dep[lca]+1;
    adde(lca,u);
    for(int i=1;i<=20;i++) f[u][i]=f[f[u][i-1]][i-1];
  }
}
int sz[N];
void dfs(int u,int father){
  sz[u]=1;
  for(int i=hd[u];i;i=nx[i]){
    int v=to[i];
    if(v==father) continue;
    dfs(v,u);
    sz[u]+=sz[v];
  }
}
int main(){
  n=read();
  for(int i=1;i<=n;i++){
    while(1){
      int x=read();
      if(x==0) break;
      adde1(i,x);
    }
  }
  topu();
  build();
  dfs(n+1,0);
  for(int i=1;i<=n;i++) printf("%d\n",sz[i]-1);
  return 0;
} 
posted @ 2021-02-23 12:04  Quick_Kk  阅读(206)  评论(0)    收藏  举报