zoukankan      html  css  js  c++  java
  • code#5 P4 逻辑树

     

    时间限制: 3.0 秒

    空间限制: 512 MB

    相关文件: 题目目录

    题目描述

    有一棵树,叫逻辑树。

    这个树有根,有 2N1 个节点,其中 N 个叶子,每个非叶节点恰好有两个孩子。

    每个叶子上有一个 01 变量,它的取值可能为 True 或 False。每个非叶节点上有一个逻辑运算符,这个运算可能为 AND 或者 OR。

    一个非叶节点的取值定义为它两个儿子的取值,作这个节点上的运算得到的结果。

    有一个黑恶势力想知道这个树的根节点的取值,他准备了一个长度为 N 的询问序列 {Pi},每个叶子在这个序列中恰好出现一次。

    黑恶势力会依次询问这些叶子的值,但是,如果他发现某一次询问是不必要的,那么他会跳过这个无意义的询问(为了帮助理解,考虑 x AND y 在我们知道 x 为 False 之后,不必知道 y 的值就可推算 x AND y 的值)。

    当然,邪恶总是能战胜正义,黑恶势力总能达到他的目的。但是我们可以拖慢他的节奏,你现在可以安排每个叶子的权值,使得黑恶势力询问的次数尽可能多,在此基础上,我们希望这个树的根节点取值尽量为 True。

    请你计算一组解,任何一种合法方案都是可以接受的。

    输入格式

    从标准输入读入数据。

    第一行一个整数 N,意义如题面所示。

    接下来一行 N1 个整数,第 i 个数代表节点 N+i 上的运算符,其中 0 表示 AND1 表示 OR

    接下来 2N2 行,每行两个整数u,v,描述一条u,v之间的边。

    最后一行 N 个整数,表示黑恶势力的询问序列。

    你可以认为 1N 是叶子,N+12N1 是非叶节点,且 N+1 是根,输入数据保证每个非叶节点有两个孩子。

    输出格式

    输出到标准输出。

    输出一个长度为 N 的 01串 S,其中 Si 表示第 i 个叶子的取值,0 为 False, 1 为 True.

    思路:

    显然这是一个特殊地树形DP

    我们首先将树上每个节点的儿子都处理出来

    然后从根节点跑第一遍DFS

    然后我们就可以通过询问的次序,处理出这个点被查到的先后

    当然为了尽可能不让黑帮老大猜到,我们会按位运算的种类分配

    父亲的值知道,当且仅当在构造情况下两个儿子的值都知道

    (我们针对位运算进行构造,与知道有0就是0,或知道有1就是1,要避免)

    这时候知道父亲的时刻就是两个儿子中后知道值的那个的时刻

    在顺序确定好后我们跑第二遍DFS

    即可确定值

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define rii register int i
    #define rij register int j
    using namespace std;
    int head[1000005],cnt,n;
    struct edge{
        int cnt,bj,s[3],val,bh;
    }x[1000005];
    struct ljb{
        int to,nxt;
    }y[4000005];
    inline void add(int from,int to)
    {
        cnt++;
        y[cnt].nxt=head[from];
        y[cnt].to=to;
        head[from]=cnt;
    }
    void ycl(int wz,int fa)
    {
        for(rii=head[wz];i;i=y[i].nxt)
        {
            int to=y[i].to;
            if(to==fa)
            {
                continue;
            }
            x[wz].s[x[wz].cnt]=to;
            x[wz].cnt++;
            ycl(to,wz);
        }
        return;
    }
    void dfs(int wz)
    {
        if(wz<=n)
        {
            return;
        }
        dfs(x[wz].s[1]);
        dfs(x[wz].s[0]);
        if(x[x[wz].s[0]].bh>x[x[wz].s[1]].bh)
        {
            swap(x[wz].s[0],x[wz].s[1]);
        }
        x[wz].bh=x[x[wz].s[1]].bh;
        return;
    }
    void dfs2(int wz)
    {
        if(wz<=n)
        {
            return;
        }
        if(x[wz].bj==0)
        {
            if(x[wz].val==0)
            {
                x[x[wz].s[0]].val=1;
                x[x[wz].s[1]].val=0;
            }
            else
            {
                x[x[wz].s[0]].val=1;
                x[x[wz].s[1]].val=1;
            }
        }
        else 
        {
            if(x[wz].bj!=0)
            {
                if(x[wz].val==0)
                {
                    x[x[wz].s[0]].val=0;
                    x[x[wz].s[1]].val=0;
                }
                   else
                {
                    x[x[wz].s[0]].val=0;
                    x[x[wz].s[1]].val=1;
                }
            }
        }
        dfs2(x[wz].s[0]);
        dfs2(x[wz].s[1]);
        return;
    }
    int main()
    {
        scanf("%d",&n);
        for(rii=n+1;i<(n<<1);i++)
        {
            scanf("%d",&x[i].bj);
        }
        for(rii=1;i<=(n-1)<<1;i++)
        {
            int from,to;
            scanf("%d%d",&from,&to);
            add(from,to);
            add(to,from);
        }
        ycl(n+1,0);
        for(rii=1;i<=n;i++)
        {
            int from;
            scanf("%d",&from);
            x[from].bh=i;
        }
        dfs(n+1);
        x[n+1].val=1;
        dfs2(n+1);
        for(rii=1;i<=n;i++)
        {
            x[i].val?putchar('1'):putchar('0');
        }
        return 0;
    }
  • 相关阅读:
    miniconda安装和使用
    linux下git push出现“更新被拒绝,因为远程仓库包含您本地尚不存在的提交。”问题的处理
    win8、win10系统添加组策略的方法
    Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?)
    thinkphp5 连接SQLserver
    thinkphp5 上传图片压缩
    在Vue中使用了Swiper ,从后台获取动态数据后,swiper滑动失效
    微信小程序多图上传及后台处理(后台用thinkphp3.2)
    PHP 数组下标从0开始
    微信小程序去除左上角返回的按钮
  • 原文地址:https://www.cnblogs.com/ztz11/p/9902175.html
Copyright © 2011-2022 走看看