poj 1463(树形dp)
题目链接:http://poj.org/problem?id=1463
思路:简单树形dp,如果不选父亲节点,则他的所有的儿子节点都必须选,如果选择了父亲节点,则儿子节点可选,可不选,取较小者。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 2222 8 #define FILL(a,b) memset(a,b,sizeof(a)) 9 10 int n,dp[MAXN][2]; 11 vector<int>g[MAXN]; 12 13 int dfs(int u,int father) 14 { 15 dp[u][0]=0,dp[u][1]=1; 16 for(int i=0;i<g[u].size();i++){ 17 int v=g[u][i]; 18 if(v==father)continue; 19 dfs(v,u); 20 dp[u][0]+=dp[v][1]; 21 dp[u][1]+=min(dp[v][0],dp[v][1]); 22 } 23 return min(dp[u][0],dp[u][1]); 24 } 25 26 27 int main() 28 { 29 int u,v,k; 30 while(~scanf("%d",&n)){ 31 for(int i=0;i<=n;i++)g[i].clear(); 32 for(int i=1;i<=n;i++){ 33 scanf("%d:(%d)",&u,&k); 34 while(k--){ 35 scanf("%d",&v); 36 g[u].push_back(v); 37 g[v].push_back(u); 38 } 39 } 40 printf("%d\n",dfs(0,-1)); 41 } 42 return 0; 43 }