LazyChild黑OJ(blackoj.pas/c/cpp)

LazyChild开了一家“善良OJ”。但大多数人都不知道,这其实是家黑OJ。亲爱的同学,请不要惊讶,古时候有黑店,现代为什么不能有黑OJ呢?每AC一道题,网站便会自动在电脑上安装一种木马。LazyChild通过窃取信息获取收益(如网游帐号、OI资料、YuanY和TT的照片等等)。

作为一名资深黑客,老Z某日突然发现,“善良OJ”上的木马,自己电脑上都没有。这可十分让他过意不去。老Z决定通过多A题,来丰富自己电脑的病毒库。

经过调查,老Z发现,很多木马是不能共存的。比如“和谐”木马与“团结”木马,两者只能任选其一。然而,老Z是个完美主义者,他想要自己的病毒库尽可能充实。

老Z不懈的追求最终感动了上天。天上的神仙(半仙?)“牛人雨”给这个问题稍稍降低了一点难度。神仙规定,对于n种木马,有且仅有(n-1)对不能共存,并且对于每种木马,都存在至少一个木马与之不能共存。

老Z不在乎自己AC多少题。请告诉他,他最多能从“善良OJ”上获取木马的个数。

【输入】

第一行,一个正整数n,表示木马个数。

剩余(n-1)行,每行一对木马,表示他们不能共存。(保证相同的木马可以共存,任意不同两行的描述不等价)

木马编号从0至(n-1)

【输入】

一行,老Z最多获得木马的个数。你可以认为开始时没有任何木马。

【输入样例】

3

0 1

1 2

【输出样例】

2

【数据规模】

对于100%的数据,1<=n<=200

 树上最大独立集 :

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 510
using namespace std;
int n,head[maxn],num,son[maxn][maxn],f[maxn][2],vis[maxn];
struct node{
    int v,pre;
}e[maxn*2];
void Add(int from,int to){
    num++;e[num].v=to;
    e[num].pre=head[from];
    head[from]=num;
}
void Dfs(int now,int from){
    if(from!=-1)
        son[from][++son[from][0]]=now;
    for(int i=head[now];i;i=e[i].pre){
        int v=e[i].v;
        if(v!=from)Dfs(v,now);
    }
}
int dp(int now,int p){
    if(f[now][p]!=-1)return f[now][p];
    int sum=0;
    if(p)sum=1;
    for(int i=1;i<=son[now][0];i++)
        if(p)sum+=dp(son[now][i],0);
        else sum+=max(dp(son[now][i],0),dp(son[now][i],1));
    return f[now][p]=sum;
}
int main()
{
    freopen("blackoj.in","r",stdin);
    freopen("blackoj.out","w",stdout);
    scanf("%d",&n);
    int u,v;
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        Add(u,v);Add(v,u);
    }
    Dfs(0,-1);
    memset(f,-1,sizeof(f));
    printf("%d\n",max(dp(0,0),dp(0,1)));
    return 0;
}
View Code

相关文章: