HDU 4340

来源:互联网 发布:学生网络兼职打字员 编辑:程序博客网 时间:2024/06/03 21:27

树形DP

看了这篇文章才懂

http://blog.csdn.net/cyberzhg/article/details/7840922

#include<cstdio>#include<cstring>#include<algorithm>#define inf 10000000using namespace std;int c[110][2];int head[110],cnt;int dp[110][2][2];    //第一维表示树的节点,第二维表示此节点取的颜色,第三维为0表示子树全取半,为1表示从子树某点开始攻击struct Edge{    int v,next;}edge[220];void addedge(int u,int v){    edge[cnt].v=v;    edge[cnt].next=head[u];    head[u]=cnt++;    edge[cnt].v=u;    edge[cnt].next=head[v];    head[v]=cnt++;}void init(){    memset(head,-1,sizeof(head));    memset(dp,0,sizeof(dp));    cnt=0;}void dfs(int u,int father){    int i,tmp1=0,tmp2=0,ans1=inf,ans2=inf;    bool flag=1;    for(i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].v;        if(v==father)continue;        dfs(v,u);        tmp1+=min(dp[v][0][0],dp[v][1][1]);        ans1=min(ans1,dp[v][0][1]-min(dp[v][0][0],dp[v][1][1]));        tmp2+=min(dp[v][1][0],dp[v][0][1]);        ans2=min(ans2,dp[v][1][1]-min(dp[v][1][0],dp[v][0][1]));    }    dp[u][0][0]=tmp1+c[u][0]/2;    dp[u][1][0]=tmp2+c[u][1]/2;    dp[u][0][1]=min(tmp1+c[u][0],tmp1+c[u][0]/2+ans1);    dp[u][1][1]=min(tmp2+c[u][1],tmp2+c[u][1]/2+ans2);}int main(){    int n,i,j,u,v;    while(scanf("%d",&n)==1){        init();        for(i=1;i<=n;i++)            scanf("%d",&c[i][0]);        for(i=1;i<=n;i++)            scanf("%d",&c[i][1]);        for(i=1;i<n;i++){            scanf("%d %d",&u,&v);            addedge(u,v);        }        dfs(1,0);        printf("%d\n",min(dp[1][0][1],dp[1][1][1]));    }}


原创粉丝点击