zoukankan      html  css  js  c++  java
  • BZOJ1304: [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

    HINT

    M<=10000

    N<=5021

    结论:根选哪个点不影响答案

    因为相邻的节点不可能相同颜色(要不然只用染其中一个就最优)

    然后就瞎jb树形DP,f[i][0/1]表示把i染成0或1的最小代价

    代码如下:

    //MT_LI
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<ctime>
    #include<map>
    #include<bitset>
    #include<set>
    #define ll long long
    #define mp(x,y) make_pair(x,y)
    #define pll pair<long long,long long>
    #define pii pair<int,int>
    using namespace std;
    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 stack[20];
    inline void write(int x)
    {
        if(x<0){putchar('-');x=-x;}
        if(!x){putchar('0');return;}
        int top=0;
        while(x)stack[++top]=x%10,x/=10;
        while(top)putchar(stack[top--]+'0');
    }
    inline void pr1(int x){write(x);putchar(' ');}
    inline void pr2(int x){write(x);putchar('
    ');}
    struct node{
        int x,y,next;
    }a[21000];int len,last[11000];
    void ins(int x,int y){a[++len]=(node){x,y,last[x]};last[x]=len;}
    int c[21000],ru[21000];
    int f[21000][2],n;
    void dp(int x,int fa)
    {
        f[x][0]=f[x][1]=1;
        if(x<=n)
        {
            f[x][c[x]]=1;
            f[x][c[x]^1]=1<<30;
        }
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y==fa)continue;
            dp(y,x);
            f[x][0]+=min(f[y][0]-1,f[y][1]);
            f[x][1]+=min(f[y][1]-1,f[y][0]);
        }
    }
    int main()
    {
        int m=read();n=read();
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)c[i]=read();
        int root;
        for(int i=1;i<m;i++)
        {
            int x=read(),y=read();
            ins(x,y);ins(y,x);ru[x]++;ru[y]++;
            if(ru[x]-1&&x>n)root=x;if(ru[y]-1&&y>n)root=y;
        }
        dp(root,0);
        pr2(min(f[root][0],f[root][1]));
        return 0;
    }
  • 相关阅读:
    jmeter压力测试
    反射【类Class、成员变量Field、方法Method】
    模块十 python标准库
    模块五 python常用数据结构
    模块四 python函数
    模块三 python控制流语法
    模块二 python基本数据类型与操作
    第四章后总结文档
    第六章节练习
    第五章节练习
  • 原文地址:https://www.cnblogs.com/MT-LI/p/10371637.html
Copyright © 2011-2022 走看看