zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    401. Binary Watch
    46. Permutations
    61. Rotate List
    142. Linked List Cycle II
    86. Partition List
    234. Palindrome Linked List
    19. Remove Nth Node From End of List
    141. Linked List Cycle
    524. Longest Word in Dictionary through Deleting
    android ListView详解
  • 原文地址:https://www.cnblogs.com/Chtholly/p/11730093.html
Copyright © 2011-2022 走看看