zoukankan      html  css  js  c++  java
  • ZJK的黑OJ(树的最大独立集)(树形DP)

    ZJK的黑OJ
    zjk开了一家“善良OJ”。这其实是家黑OJ。每AC一道题,网站便会自动在电脑上安装一种木马。zjk通过窃取信息获取收益(如网游帐号、OI资料、和KK的照片等等)。
    作为一名资深黑客,老Z某日突然发现,“善良OJ”上的木马,自己电脑上都没有。这可十分让他过意不去。老Z决定通过多A题,来丰富自己电脑的病毒库。
    经过调查,老Z发现,很多木马是不能共存的。比如“和谐”木马与“团结”木马,两者只能任选其一。然而,老Z是个完美主义者,他想要自己的病毒库尽可能充实。
    老Z不懈的追求最终感动了上天。天上的神仙lemon给这个问题稍稍降低了一点难度。神仙规定,对于n种木马,有且仅有(n-1)对不能共存,并且对于每种木马,都存在至少一个木马与之不能共存。
    老Z不在乎自己AC多少题。请告诉他,他最多能从“善良OJ”上获取木马的个数。
    【输入】
    第一行,一个正整数n,表示木马个数。
    剩余(n-1)行,每行一对木马,表示他们不能共存。(保证相同的木马可以共存,任意不同两行的描述不等价)
    木马编号从0至(n-1)
    【输入】
    一行,老Z最多获得木马的个数。你可以认为开始时没有任何木马。
    【输入样例】
    3
    0 1
    1 2
    【输出样例】
    2
    【数据规模】
    对于100%的数据,1<=n<=200

    /*
    不建树.
    用链表搞.
    双向建边. 
    只需要判断father和son是否一样. 
    然后裸的树上最大独立集.
    用树形DP搞. 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 1001
    using namespace std;
    int tot,fa[MAXN][3],w[MAXN],head[MAXN],n;
    struct data
    {
        int v,next,x;
    }e[MAXN];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v)
    {
        e[++tot].v=v;
        e[tot].next=head[u];
        head[u]=tot;
    }
    void dfs(int father,int u)
    {
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(v==father) continue;
            dfs(u,v);
            fa[u][0]+=max(fa[v][0],fa[v][1]);
            fa[u][1]+=fa[v][0];
        }
    }
    int main()
    {
    
        int x,y;
        n=read();
        for(int i=1;i<=n;i++) fa[i][1]=1;
        for(int i=1;i<n;i++)
        {
            x=read();y=read();
            x++;y++;
            add(x,y);add(y,x);
        }
        dfs(0,1);
        printf("%d
    ",max(fa[1][0],fa[1][1]));
        return 0;
    }
    /*
    先建树.
    不然没法确定点的关系.
    然后裸的树上最大独立集.
    用树形DP搞. 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 1001
    using namespace std;
    int tot,fa[MAXN][3],w[MAXN],head[MAXN],father[MAXN],son[MAXN][MAXN],n;
    struct data
    {
        int v,next,x;
    }e[MAXN];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v)
    {
        e[++tot].v=v;
        e[tot].next=head[u];
        head[u]=tot;
    }
    void build(int x)
    {
        for(int i=head[x];i;i=e[i].next)
        {
            int t=e[i].v;
            if(!father[t])
            {
                father[t]=x;
                son[x][++son[x][0]]=t;
                build(t);
            }
        }
    }
    void dfs(int u)
    {
        if(fa[u][1])return;
        fa[u][1]=1;
        for(int i=1;i<=son[u][0];i++)
        {
            int v=son[u][i];
            dfs(v);
            fa[u][0]+=max(fa[v][0],fa[v][1]);
            fa[u][1]+=fa[v][0];
        }
    }
    int main()
    {
    
        int x,y;
        n=read();
        for(int i=1;i<n;i++)
        {
            x=read();y=read();
            x++;y++;
            add(x,y);
            add(y,x);
        }
        father[1]=1;
        build(1);
        dfs(1);
        printf("%d
    ",max(fa[1][0],fa[1][1]));
        return 0;
    }
  • 相关阅读:
    JAVA for(i = 0; i<a.length; i++) 解析
    3.2.2多维数组 3.3 排序
    3.2数组
    字符串和数组
    2.7.3与程序转移有关的跳转语句
    2.7.2 循环语句
    读书共享 Primer Plus C-part 4
    Linux 批量修改文件名
    关于/usr/local/lib/libz.a(zutil.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC解决办法
    做一个有深度的程序猿
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070776.html
Copyright © 2011-2022 走看看