POJ 1947 Rebuilding Roads(树形DP)
树形DP慢慢来,慢慢学习。这个题,就是树上的背包。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 #define INF 100000000 8 int dp[501][501]; 9 int first[501]; 10 int o[501],m,t; 11 struct node 12 { 13 int u,v,next; 14 }edge[1000000]; 15 void CL() 16 { 17 t = 1; 18 memset(first,-1,sizeof(first)); 19 memset(o,0,sizeof(o)); 20 } 21 void add(int u,int v) 22 { 23 edge[t].u = u; 24 edge[t].v = v; 25 edge[t].next = first[u]; 26 first[u] = t++; 27 } 28 void dfs(int x) 29 { 30 int i,j,k,temp; 31 for(i = 0;i <= m;i ++) 32 dp[x][i] = INF; 33 dp[x][1] = 0; 34 for(i = first[x];i != -1;i = edge[i].next) 35 { 36 dfs(edge[i].v); 37 for(j = m;j >= 1;j --) 38 { 39 temp = dp[x][j] + 1; 40 for(k = 1;k < j;k ++) 41 { 42 temp = min(temp,dp[edge[i].v][j-k]+dp[x][k]); 43 } 44 dp[x][j] = temp; 45 } 46 } 47 } 48 int main() 49 { 50 int n,i,u,v,ans; 51 while(scanf("%d%d",&n,&m)!=EOF) 52 { 53 CL(); 54 for(i = 1;i < n;i ++) 55 { 56 scanf("%d%d",&u,&v); 57 add(u,v); 58 o[v] = 1; 59 } 60 for(i = 1;i <= n;i ++) 61 { 62 if(o[i] == 0) 63 { 64 dfs(i); 65 ans = dp[i][m]; 66 break; 67 } 68 } 69 for(i = 1;i <= n;i ++) 70 { 71 ans = min(ans,dp[i][m]+1); 72 } 73 printf("%d\n",ans); 74 } 75 return 0; 76 }