POJ1463->树形DP

来源:互联网 发布:考上清华 知乎 编辑:程序博客网 时间:2024/06/10 18:18
//树形DP//树的最小点覆盖//f[x][1]以x为根的子树在x上放置的士兵的最少所需的士兵数目//f[x][0]以x为根的子树x上不放置的士兵的最少所需的士兵数目//状态转移方程://如果当前节点选取,则其子节点可选可不选dp[root][1] += min(dp[tree[root][i]][1],dp[tree[root][i]][0]) ;//如果当前节点不选,则其子节点必须选    dp[root][0] += dp[tree[root][i]][1] ;#include <stdio.h>#include <iostream>#include <vector>#include <string.h>using namespace std ;#define MAX 1510vector<int>tree[MAX] ;int f[MAX] , n , dp[MAX][2];void DFS(int root){    dp[root][0]=0;    dp[root][1]=1;    int len = tree[root].size();    for(int i = 0 ; i < len ; i ++)    {        DFS(tree[root][i]) ;    }    for(int i = 0 ; i < len ; i ++)    {        dp[root][1] += min(dp[tree[root][i]][1],dp[tree[root][i]][0]) ;        dp[root][0] += dp[tree[root][i]][1] ;    }}int main(){    int edge , fa , son ;    while(scanf("%d",&n)!=EOF)    {        memset(f , -1 , sizeof(f)) ;        for(int i = 1 ; i <= n ; i ++)        {            scanf("%d:(%d)", &fa , &edge);            //dp[i][0] = 0 ;            //dp[i][1] = 1 ;            tree[fa].clear();            while(edge --)            {                scanf("%d",&son) ;                tree[fa].push_back(son) ;                f[son] = fa ;            }        }        int a = 1 ;        while(f[a]!= -1) a=f[a];        DFS(a);        printf("%d\n" , min(dp[a][0],dp[a][1])) ;    }    return 0 ;}

0 0
原创粉丝点击