zoukankan      html  css  js  c++  java
  • 【CQOI2009】叶子的颜色

    Description
      给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根、内部结点和叶子均可)着以黑色或白色。你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一个有色结点(哪怕是这个叶子本身)。
      对于每个叶结点u,定义c[u]为从u到根结点的简单路径上第一个有色结点的颜色。给出每个c[u]的值,设计着色方案,使得着色结点的个数尽量少。

    Input
      第一行包含两个正整数m, n,其中n是叶子的个数,m是结点总数。结点编号为1,2,…,m,其中编号1,2,… ,n是叶子。以下n行每行一个0或1的整数(0表示黑色,1表示白色),依次为c[1],c[2],…,c[n]。以下m-1行每行两个整数a,b(1<=a < b <= m),表示结点a和b 有边相连。

    Output
      仅一个数,即着色结点数的最小值。

    Sample Input
    5 3
    0
    1
    0
    1 4
    2 5
    4 5
    3 5

    Sample Output
    2

    Data Constraint

    Hint
    【数据范围】  
      1<=N,M<=100000
    .
    .
    .
    .
    .
    .

    分析

    选择任意一个点为根,答案都是相同的。
    假如原来以x为根,y与x相邻,那么x与y的颜色不可能相同。既然颜色不同,那么将根从x变成y对答案显然也不会产生影响。
    所以随便选一个点为根,然后树形DP。用f[x][0/1]表示x的子树中,最后一个点想要得到一个白色/黑色的祖先的最小代价。
    .
    .
    .
    .
    .

    程序:
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int to[100000],cnt,from[100000],head[100000],f[100000][2],n,m,inf=2147483647,c[100000];
    void insert(int x,int y)
    {
        to[++cnt]=y; from[cnt]=head[x]; head[x]=cnt;
    }
    void dp(int root,int fa)
    {
        f[root][0]=f[root][1]=1;
        if (root<=m) if (c[root]) f[root][0]=inf; else f[root][1]=inf;
        for (int i=head[root];i;i=from[i])
        {
            if (to[i]!=fa)
            {
                dp(to[i], root);
                f[root][0]+=min(f[to[i]][0]-1,f[to[i]][1]);
                f[root][1]+=min(f[to[i]][1]-1,f[to[i]][0]);
            }
    
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++) 
        scanf("%d",&c[i]);
        for (int i=1;i<=n-1;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            insert(x,y); insert(y,x);
        }
        dp(m+1,-1);
        printf("%d",min(f[m+1][1],f[m+1][0]));
        return 0;
    }
  • 相关阅读:
    汇编--立即数
    java mysql常用函数大全
    java springboot@GeneratedValue 注解
    java list.stream().map().collect(Collectors.toList())
    java 一种树的写法
    怎么查看当前进程?怎么执行退出?怎么查看当前路径?
    垃圾回收的优点和原理,并考虑2种回收机制?
    du 和 df 的定义,以及区别?
    通过什么命令查找执行命令?
    终端是哪个文件夹下的哪个文件?黑洞文件是哪个文件夹下的哪个命令?
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/9499938.html
Copyright © 2011-2022 走看看