zoukankan      html  css  js  c++  java
  • BZOJ 1304: [CQOI2009]叶子的染色

    二次联通门 : BZOJ 1304: [CQOI2009]叶子的染色

    /*
        BZOJ 1304: [CQOI2009]叶子的染色
        
        此题最难解决的就是关于根的问题
        但是自己手动模拟会发现
        无论哪个非叶子节点做根,对答案都是没有影响的
        所以随便确定一个根,做树形dp
        dp[i][0]表示以i为根的子树染白色的最小代价
        dp[1][1]同理
    */
    #include <cstdio>
    #include <iostream>
    
    const int BUF = 12312323;
    char Buf[BUF], *buf = Buf;
    #define INF 1e9
    inline void read (int &now)
    {
        for (now = 0; !isdigit (*buf); ++ buf);
        for (; isdigit (*buf); now = now * 10 + *buf - '0', ++ buf);
    }
    #define Max 100001
    struct E { E *n; int v; }; int c[Max], dp[Max][2], N, M;
    E *list[Max], poor[Max << 2], *Ta = poor;
    inline int min (int a, int b) { return a < b ? a : b; }
    void Dp (int n, int F)
    {
        dp[n][0] = dp[n][1] = 1;
        if (n <= M) dp[n][c[n] ^ 1] = INF;
        for (E *e = list[n]; e; e = e->n)
            if (e->v != F) 
            {
                Dp (e->v, n);
                dp[n][0] += min (dp[e->v][0] - 1, dp[e->v][1]);
                dp[n][1] += min (dp[e->v][1] - 1, dp[e->v][0]);
            }
    }
    int Main ()
    {
        fread (buf, 1, BUF, stdin);
        int x, y; read (N), read (M); register int i, j;
        for (i = 1; i <= M; ++ i) read (c[i]);
        for (i = 1; i < N; ++ i)
        {
            read (x), read (y);
            ++ Ta, Ta->v = y, Ta->n = list[x], list[x] = Ta;
            ++ Ta, Ta->v = x, Ta->n = list[y], list[y] = Ta;
        }
        Dp (M + 1, 0); printf ("%d", min (dp[M + 1][0], dp[M + 1][1]));
        return 0;
    }
    int ZlycerQan = Main ();
    int main (int argc, char *argv[]) {;}
  • 相关阅读:
    读Android之大话设计模式--前言和说明
    把二叉树打印成多行
    按之字形顺序打印二叉树
    对称的二叉树
    二叉树的下一个结点
    链表中环的入口结点
    字符流中第一个不重复的字符
    表示数值的字符串
    构建乘积数组
    数组中重复的数字
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7492009.html
Copyright © 2011-2022 走看看