标签:
Description
Sample Input
4 0:(1) 1 1:(2) 2 3 2:(0) 3:(0) 5 3:(3) 1 4 2 1:(1) 0 2:(0) 0:(0) 4:(0)
Sample Output
1 2
给出有向图,要求找出用最少的人数可以看守所有的边。
dp[i][0] 以i为根的子树,i上不放人时,需要的最少人数。
dp[i][1] 以i为根的子树,i上放人时,需要的最少人数。
状态转移方程:j为i的子节点
dp[i][0] += dp[j][1] ;
dp[i][1] += max( dp[j][0],dp[j][1] ) ;
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; struct node{ int u , v ; int next ; }edge[2000]; int head[2000] , cnt ; int dp[2000][2] ; void add(int u,int v) { edge[cnt].u = u ; edge[cnt].v = v; edge[cnt].next = head[u] ; head[u] = cnt++ ; return ; } void dfs(int u) { int i , v ; dp[u][0] = 0 ; dp[u][1] = 1 ; for(i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v ; dfs(v) ; dp[u][0] += dp[v][1] ; dp[u][1] += min(dp[v][0],dp[v][1]) ; } return ; } int main() { int n , m , i , j , u , v , rt ; while( scanf("%d", &n) != EOF ) { cnt = 0 ; rt = (n-1)*(n)/2 ; memset(head,-1,sizeof(head)) ; memset(dp,0,sizeof(dp)) ; for(i = 0 ; i < n ; i++) { scanf("%d:(%d)", &u, &m) ; while( m-- ) { scanf("%d", &v) ; add(u,v) ; rt -= v ; } } dfs(rt) ; printf("%d\n", min(dp[rt][0],dp[rt][1])) ; } return 0; }
poj1463--hdu1054--Strategic Game(树形DP练习4)
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42834113