zoukankan      html  css  js  c++  java
  • 10.20testT3

    3、编译
    compiler.cpp/in/out
    1s / 128M
    [Description]
    山山是 2017 级信奥班的成员,因为喜欢玩 Android 系统而出名。
    山山写出了一个伟大的 C++工程,一共包含 N 个源文件。在山山的脑海中,N 个源文
    件构成一个树形结构。每一个源文件是树上的一个节点,其中 1 号节点是树根。
    现在,山山开始编译这个工程。每次他会从树上选择一条链(包含两个端点)进行编译。
    由于编译器的特性,要求这条链的一个端点必须是另一个端点的祖先。一条链可以退化成一
    个点。每个源文件都需要被编译恰好一次。
    每一个源文件都有一个两位十六进制数的标志值(范围从 00 到 ff)。对于每一条选择的
    链,把该上面所有源文件的标志值异或起来,得到这条链的特征值。把所有选择的链的特征
    值相加,得到这次编译的代价。现在山山想知道至少选择几条链才能编译所有文件。在选择
    的链数目最小的时候,编译的代价最小是多少。
    [Input]
    第一行一个整数 N。
    以下一行,N 个两位十六进制数,表示第 1 号源文件到第 N 号源文件的特征值。
    (十六进制
    数中的字母采取小写,不足两位的在前面补零。亦即 C/C++中使用”%02x”输出的格式。
    )
    以下(N - 1)行,每行两个整数,给出树上的一条边所连接的两个顶点。
    [Output]
    一行两个整数。依次为,选择的链的最小数目、编译的最小代价。两个数均以十进制形式输

    [Tips]
    0 ≤ N ≤ 20,000。

    首先链数目最小就是叶子节点的个数,叶子节点必然成为链的下端点,因为它不能当任何人的祖先。

    要怎么球最小异或和呢,首先想到暴力深搜,得到每种决策的答案,然后每层决策取最优。

    由于如果一个节点有两个儿子,必然有一个儿子与当前节点异或,另一个儿子以自己为端点递归下去产生新链,这里不同的决策只与最终和当前节点异或的值相关,于是我们采取记搜,将节点异或值保存进数组,定义 dp[u][s] 为考虑子树 u ,并且点 u 所属的链当前的异或和为 s 时的最小代价。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define N 20010
    using namespace std;
    int n,w[N],u,v,cnt,anss=2e9,ans1,ans,head[N],sz[N],f[N][310];
    char ch[3];
    bool vis[N],vv[N];
    struct node{
        int next,to;
    }e[N*10];
    void add(int u,int v)
    {
        e[++cnt].next=head[u],e[cnt].to=v,head[u]=cnt;
    }
    void dfs1(int u,int fa)
    {
        for(int i=head[u];i;i=e[i].next)
        {
        int v=e[i].to;
        if(v==fa)continue;
        dfs1(v,u);
        sz[u]+=sz[v];
        }
        sz[u]=max(sz[u],1);
    }
    int dfs(int u,int fa,int cost)
    {
        if(f[u][cost])return f[u][cost];
        int fl=0,sum=2e9; 
        for(int i=head[u];i;i=e[i].next)
        {
        int v=e[i].to,res;
        if(v==fa)continue;
        fl=1;
        res=dfs(v,u,cost^w[v]);
        for(int j=head[u];j;j=e[j].next)
            if(e[j].to!=fa&&e[j].to!=v)res+=dfs(e[j].to,u,w[e[j].to]);
        sum=min(sum,res);
        }
        if(!fl)return f[u][cost]=cost;
        return f[u][cost]=sum;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%02x",&w[i]);
        for(int i=1;i<=n-1;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
        dfs1(1,0);
        ans1=sz[1];
        int anss=dfs(1,0,w[1]);
        printf("%d %d\n",ans1,anss);
        return 0;
    }
  • 相关阅读:
    技术服务支持
    如何将Java Web项目部署到服务器上
    移动端前端开发——微信左上角返回按钮(JQMobile)
    Mac下phpstorm 浏览器出现 502 bad gateway 解决办法
    mysql sql语句大全
    复制自己的ssh-key
    PhpStorm环境搭建
    max下搭建XAMPP
    Cocopods第三方库管理工具创建Swift项目&OC项目就
    Swift-闭包
  • 原文地址:https://www.cnblogs.com/lxykk/p/7701802.html
Copyright © 2011-2022 走看看