• CF613D Kingdom and its Cities 虚树 + 树形DP


    Code: 

    #include<bits/stdc++.h>
    #define ll long long  
    #define maxn 300003 
    #define RG register
    using namespace std; 
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    inline void setIO(string s) 
    {
    	string in=s+".in", out=s+".out"; 
    	freopen(in.c_str(),"r",stdin); 
    }
    int edges,tim,n;  
    int hd[maxn], to[maxn<<1], nex[maxn<<1];  
    inline void add(int u,int v) 
    {
    	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
    }
    int fa[maxn], top[maxn], dfn[maxn], hson[maxn], siz[maxn], dep[maxn]; 
    void dfs1(int u,int ff)
    { 
    	siz[u]=1,fa[u]=ff,dfn[u]=++tim,dep[u]=dep[ff]+1; 
    	for(int i=hd[u];i;i=nex[i])
    	{
    		int v=to[i];
    		if(v==ff) continue; 
    		dfs1(v, u); 
    		siz[u]+=siz[v]; 
    		if(siz[v]>siz[hson[u]]) hson[u]=v;   
    	}
    } 
    void dfs2(int u,int tp)
    {
    	top[u]=tp; 
    	if(hson[u]) dfs2(hson[u], tp); 
    	for(int i=hd[u];i;i=nex[i])
    	{
    		int v=to[i]; 
    		if(v==fa[u]||v==hson[u]) continue; 
    		dfs2(v,v);       
    	}
    } 
    inline int LCA(int x,int y)
    {
    	while(top[x]!=top[y]) 
    	{
    		dep[top[x]] > dep[top[y]] ? x = fa[top[x]] : y = fa[top[y]]; 
    	}
    	return dep[x] < dep[y] ? x : y;   
    }       
    int tp; 
    vector<int>G[maxn]; 
    int arr[maxn],mk[maxn],S[maxn],g[maxn],f[maxn];           
    int cmp(int i,int j) 
    {
    	return dfn[i]<dfn[j];              
    }
    inline void addvir(int u,int v)
    {
    	G[u].push_back(v); 
    }
    inline void insert(int x)
    { 
    	if(tp<=1) { S[++tp]=x;  return; } 
    	int lca=LCA(x, S[tp]); 
    	if(lca==S[tp]) { S[++tp]=x; return; }  
    	while(tp > 1 && dep[S[tp - 1]] >= dep[lca]) addvir(S[tp-1], S[tp]), --tp; 
    	if(S[tp]!=lca) addvir(lca,S[tp]), S[tp]=lca;  
    	S[++tp]=x;         
    } 
    void DP(int x)
    {    
    	g[x]=f[x]=0;
    	for(int i=0;i<G[x].size();++i) 
    	{  
    		int v = G[x][i];       
    		DP(v); 
    		f[x]+=f[v];    
    		g[x]+=g[v];   
    	}                 
    	if(mk[x]) f[x]+=g[x], g[x]=1; 
    	else f[x]+=(g[x]>1), g[x]=(g[x]==1);               
    	G[x].clear();  
    }    
    inline void work() 
    {   
    	int k=read();                 
    	for(int i=1;i<=k;++i) arr[i]=read(), mk[arr[i]]=1; 
    	sort(arr+1,arr+1+k,cmp);       
        for(int i=1;i<=k;++i) 
        	if(mk[arr[i]]&&mk[fa[arr[i]]])                       
        	{
        		for(int j=1;j<=k;++j) mk[arr[j]]=0; 
        		printf("-1
    "); 
        		return; 
        	}      
        tp=0;   
        if(arr[1]!=1) S[tp=1]=1; 
        for(int i=1;i<=k;++i) insert(arr[i]); 
        while(tp > 1) addvir(S[tp - 1], S[tp]), --tp;       
        DP(1);         
        printf("%d
    ",f[1]);   
        for(int j=1;j<=k;++j) mk[arr[j]]=0;
    }
    int main()
    {
    	// setIO("input");  
    	n=read(); 
    	for(int i=1,a,b;i<n;++i) 
    	{
    		a=read(),b=read(); 
    		add(a,b), add(b,a);                                 
    	} 
    	dfs1(1,0), dfs2(1,1); 
    	int Q; 
    	Q=read(); 
    	for(int i=1;i<=Q;++i) work(); 
    	return 0; 
    }
    

      

  • 相关阅读:
    cookie
    sql 语句
    页面宽高
    分页
    asp.net中如何防止用户重复点击提交按钮
    小试简单工厂模式之简单计算器
    用函数实现交换的疑问
    结构体变量输入输出的问题
    scanf函数输入float数需要注意的问题
    oracle学习手记(1)
  • 原文地址:https://www.cnblogs.com/guangheli/p/11131229.html
Copyright © 2020-2023  润新知