[CSP校内集训]attack(DAG支配树)

Posted chtholly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CSP校内集训]attack(DAG支配树)相关的知识,希望对你有一定的参考价值。

题意

给一个DAG,多次询问,每次给定(k)个点,求1到这些点的必经点的交集大小

思路

支配树裸题,建好DAG的支配树后(k)个点LCA的深度即为答案

Code

#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n,m,q;
int rd[N],f[N][18],dep[N];

struct Edge
{
    int next,to;
}edge[N<<1],edge1[N<<1];int head[N],head1[N],cnt,cnt1;
void add_edge(int from,int to) {edge[++cnt].next=head[from]; edge[cnt].to=to; head[from]=cnt;}
void add_edge1(int from,int to) {edge1[++cnt1].next=head1[from]; edge1[cnt1].to=to; head1[from]=cnt1;}

template <class T>
void read(T &x)
{
    char c;int sign=1;
    while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    while((c=getchar())>='0'&&c<='9') x=x*10+c-48; x*=sign;
}
int lca(int x,int y)
{
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=17;i>=0;--i) if(dep[f[x][i]]>=dep[y]) 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 toposort()
{
    queue<int> q;
    q.push(1);
    while(!q.empty())
    {
        int u=q.front(),now=-1; q.pop();
        for(int i=head1[u];i;i=edge1[i].next)
        {
            int v=edge1[i].to;
            if(now==-1) now=v;
            else now=lca(now,v);
        }
        if(now==-1) dep[u]=1;
        else
        {
            dep[u]=dep[now]+1;
            f[u][0]=now;
            for(int i=1;i<=17;++i) f[u][i]=f[f[u][i-1]][i-1];
        }
        
        for(int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(--rd[v]==0) q.push(v);
        }
    }
}
int main()
{
    freopen("attack.in","r",stdin);
    freopen("attack.out","w",stdout);
    read(n);read(m);read(q);
    for(int i=1;i<=m;++i)
    {
        int x,y;
        read(x);read(y);
        add_edge(x,y);
        add_edge1(y,x);
        ++rd[y];
    }
    toposort();
    while(q--)
    {
        int k; read(k);
        int x,y; read(x);
        for(int i=2;i<=k;++i)
        {
            read(y);
            x=lca(x,y);
        }
        printf("%d
",dep[x]);
    }
    return 0;
}

以上是关于[CSP校内集训]attack(DAG支配树)的主要内容,如果未能解决你的问题,请参考以下文章

11.5 两次考试

[CSP校内集训]rank

[CSP校内集训]tree(期望DP)

[CSP校内集训]矩形面积交(树状数组)

[CSP校内集训]贪吃蛇(阿尔法-贝塔剪枝)

hdu 6604 DAG上的支配树(灭绝树)