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 }

 

 

 

你可能感兴趣的:(Build)