[bzoj2060][Usaco2010 Nov]Visiting Cows 拜访奶牛_树形dp

Visiting Cows 拜访奶牛 bzoj-2060 Usaco-2010 Nov

题目大意题目链接

注释:略。


想法:看起来像支配集。

只是看起来像而已。

状态:dp[pos][flag]表示以pos为根的子树中,i选(不选)的最大收益。

转移:dp[pos][0]+=max(dp[to[i]][0],dp[to[i]][1]);dp[pos][1]+=dp[to[i]][0]。

最后,附上丑陋的代码... ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 50010
using namespace std;
int to[N<<2],nxt[N<<2],head[N],tot,dp[N][3];
inline char nc()
{
    static char *p1,*p2,buf[100000];
    return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
int read()
{
    int x=0; char c=nc();
    while(!isdigit(c)) c=nc();
    while(isdigit(c)) x=(x<<3)+(x<<1)+c-'0',c=nc();
    return x;
}
inline void add(int x,int y)
{
    to[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void dfs(int pos,int fa)
{
    dp[pos][1]=1;
    dp[pos][2]=0;
    for(int i=head[pos];i;i=nxt[i])
    {
        if(to[i]==fa) continue;
        dfs(to[i],pos);
        dp[pos][1]+=dp[to[i]][2];
        dp[pos][2]+=max(dp[to[i]][1],dp[to[i]][2]);
    }
}
int main()
{
    int n=read();
    for(int x,y,i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
    dfs(1,1);
    printf("%d\n",max(dp[1][1],dp[1][2]));
    return 0;
}

小结:树形dp裸题。

posted @   JZYshuraK_彧  阅读(151)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示