BZOJ 1369 树形DP

思路:
f[i][j] 表示节点i 染成j时 子树的最小权值
(我会猜这个j很小 你打我吖~)
随便DP一发就好了 (证明我也不会)

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=20050,inf=0x3f3f3f3f;
int v[N],next[N],first[N],tot,n,xx,yy,f[N][21],ans=inf;
void add(int x,int y){v[++tot]=y,next[tot]=first[x],first[x]=tot;}
void dfs(int x,int fa){
    for(int i=1;i<=20;i++)f[x][i]=i;
    for(int i=first[x];i;i=next[i])if(v[i]!=fa)dfs(v[i],x);
    for(int j=1;j<=20;j++)
        for(int i=first[x];i;i=next[i])if(v[i]!=fa){
            int temp=inf;
            for(int k=1;k<=20;k++)if(j!=k)temp=min(temp,f[v[i]][k]);
            f[x][j]+=temp;
        }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++)scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx);
    dfs(1,-1);
    for(int i=1;i<=20;i++)ans=min(ans,f[1][i]);
    printf("%d\n",ans);
}

posted @ 2017-02-15 00:13  SiriusRen  阅读(141)  评论(0编辑  收藏  举报