zoukankan      html  css  js  c++  java
  • CF613D

    这是个假题吧...

    首先显然上虚树了

    然后我们考虑一下最优策略:

    如果虚树两节点都是关键点,那么这两点之间至少选一个

    如果一个节点本身是关键点,那么我们必须覆盖下下面所有点

    如果一个节点本身不是关键点,那么这个点可选可不选,这一点要基于下面有多少个上来来决定

    也就是说,我们在虚树上dfs的过程中需要考虑到每个子节点向上会传递多少个节点,也就是说每个节点选最少的情况下可能不能完全封死下面的点,可能会向上传递一些节点,这时我们就需要处理这个问题

    但是向上传递一部分节点一定是更优的,因为我们这时只需选一个LCA即可堵住多个节点

    因此我们直接讨论:如果当前点不是关键点而底下传上来的点数>1,那么这个点就需要选

    如果这个点本身就是关键点,那么就要封上所有底下传上来的点,然后向上传一个点即可

    贴代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <map>
    using namespace std;
    struct Edge
    {
        int nxt;
        int to;
    }edge[200005];
    int head[100005];
    int f[100005][25];
    int inr[100005],our[100005],dep[100005];
    int my_stack[100005],mine_stack[100005];
    bool bas[100005],vis[100005];
    int dp[100005];
    vector <int> v[100005];
    map <int,int> acc[100005];
    int deep=0;
    int cnt=1;
    int n,q,m;
    void add(int l,int r)
    {
        edge[cnt].nxt=head[l];
        edge[cnt].to=r;
        acc[l][r]=1;
        head[l]=cnt++;
    }
    void dfs(int x,int fx)
    {
        f[x][0]=fx,inr[x]=++deep,dep[x]=dep[fx]+1;
        for(int i=1;i<=20;i++)f[x][i]=f[f[x][i-1]][i-1];
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int to=edge[i].to;
            if(to==fx)continue;
            dfs(to,x);
        }
        our[x]=++deep;
    }
    bool cmp(int x,int y)
    {
        return inr[x]<inr[y];
    }
    int LCA(int x,int y)
    {
        if(dep[x]>dep[y])swap(x,y);
        for(int i=20;i>=0;i--)if(dep[f[y][i]]>=dep[x])y=f[y][i];
        if(x==y)return x;
        int ret;
        for(int i=20;i>=0;i--)
        {
            if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
            else ret=f[x][i];
        }
        return ret;
    }
    bool be_in(int x,int y)//y in x
    {
        return inr[y]>inr[x]&&our[y]<our[x];
    }
    int redfs(int x)
    {
        int temp=0;
        for(int i=0;i<v[x].size();i++)
        {
            int to=v[x][i];
            if(bas[x]&&bas[to]&&acc[x][to])return -1;
            int t=redfs(to);
            if(t==-1)return -1;
            temp+=t;
            dp[x]+=dp[to];
        }
        if(!bas[x]){if(temp>1)temp=0,dp[x]++;}
        else dp[x]+=temp,temp=1;
        return temp;
    }
    inline int read()
    {
        int f=1,x=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int main()
    {
        n=read();
        for(int i=1;i<n;i++)
        {
            int x=read(),y=read();
            add(x,y),add(y,x);
        }
        dfs(1,1);
        q=read();
        while(q--)
        {
            m=read();
            for(int i=1;i<=m;i++)my_stack[i]=read(),bas[my_stack[i]]=vis[my_stack[i]]=1;
            sort(my_stack+1,my_stack+m+1,cmp);
            int t=m;
            for(int i=1;i<m;i++)
            {
                int fa=LCA(my_stack[i],my_stack[i+1]);
                if(!vis[fa])vis[fa]=1,my_stack[++t]=fa;
            }
            sort(my_stack+1,my_stack+t+1,cmp);
            int T1=0,rt;
            for(int i=1;i<=t;i++)
            {
                while(T1&&!be_in(mine_stack[T1],my_stack[i]))T1--;
                if(!T1)rt=my_stack[i];
                else v[mine_stack[T1]].push_back(my_stack[i]);
                mine_stack[++T1]=my_stack[i];
            }
            int tmp=redfs(rt);
            if(tmp==-1)printf("-1
    ");
            else printf("%d
    ",dp[rt]);
            for(int i=1;i<=t;i++)v[my_stack[i]].clear(),dp[my_stack[i]]=bas[my_stack[i]]=vis[my_stack[i]]=0;
        }
        return 0;
    }
  • 相关阅读:
    Jmeter逻辑控制器
    python学习笔记——%占位符的使用
    python学习笔记——生成随机数
    python学习笔记——变量的规则
    loadrunner11中HTTP/HTML的HTML-base script的两种script type有什么区别?
    loadrunner11如何实时查看脚本的运行情况?
    loaderunner11回放脚本时如何设置【运行时行为】?
    appium学习笔记之——popupwindow控件元素无法定位
    Chrome、Firefox、IE等浏览器驱动diver程序存放目录
    npm方式安装appium环境所遇到的各种问题
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11147930.html
Copyright © 2011-2022 走看看