ZJK的黑OJ(树的最大独立集)(树形DP)

来源:互联网 发布:恒指期货实时行情数据 编辑:程序博客网 时间:2024/06/13 09:15

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 1001using 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\n",max(fa[1][0],fa[1][1]));    return 0;}
/*先建树.不然没法确定点的关系.然后裸的树上最大独立集.用树形DP搞. */#include<iostream>#include<cstdio>#include<cstring>#define MAXN 1001using 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\n",max(fa[1][0],fa[1][1]));    return 0;}
0 0
原创粉丝点击