SPOJ 1435 Vertex Cover 树形DP

i 表示节点 i ,j=0表示不选择其父节点,j=1表示选择其父节点。f 为其父节点。

取 每个节点选择/不选择 两者中较小的那个。

一组数据:

15
1 2
1 3
1 4
1 10
10 9
10 11
12 10
12 14
10 13
13 15
4 5
5 7
4 6
6 8

答案是6

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <cstdlib>

 4 #include <algorithm>

 5 #include <vector>

 6 

 7 using namespace std;

 8 

 9 const int MAXN = 100010;

10 

11 vector<int> adj[MAXN];

12 bool vis[MAXN][2];

13 int d[MAXN][2];

14 int n, m;

15 //int path[MAXN][2];

16 //int fang[MAXN];

17 

18 int dp( int i, int j, int f )

19 {

20     if ( vis[i][j] ) return d[i][j];

21     vis[i][j] = true;

22     int &ans = d[i][j];

23 

24     ans = 1;

25     for ( int k = 0; k < (int)adj[i].size(); ++k )

26     if ( adj[i][k] != f ) ans += dp( adj[i][k], 1, i );

27     //path[i][j] = f;

28 

29     if ( j || f < 0 )

30     {

31         int sum = 0;

32         for ( int k = 0; k < (int)adj[i].size(); ++k )

33         if ( adj[i][k] != f )

34            sum += dp( adj[i][k], 0, i );

35         if ( sum < ans )

36         {

37             ans = sum;

38             //path[i][j] = -f;

39         }

40     }

41     return ans;

42 }

43 

44 //void DFS( int i, int j, int f )

45 //{

46 //    if ( fang[i] != -1 ) return;

47 //    if ( !path[i][j] || path[i][j] == f )

48 //    {

49 //        if ( f >= 0 ) fang[f] = j;

50 //        for ( int k = 0; k < (int)adj[i].size(); ++k )

51 //            if ( adj[i][k] != f ) DFS( adj[i][k], 1, i );

52 //    }

53 //    else

54 //    {

55 //        if ( f >= 0 ) fang[f] = j;

56 //        for ( int k = 0; k < (int)adj[i].size(); ++k )

57 //            if ( adj[i][k] != f ) DFS( adj[i][k], 0, i );

58 //

59 //    }

60 //    return;

61 //}

62 

63 int main()

64 {

65     while ( ~scanf( "%d", &n ) )

66     {

67         m = n - 1;

68         for ( int i = 0; i <= n; ++i ) adj[i].clear();

69 

70         for ( int i = 0; i < m; ++i )

71         {

72             int a, b;

73             scanf( "%d%d", &a, &b );

74             adj[a].push_back(b);

75             adj[b].push_back(a);

76         }

77 

78         memset( vis, false, sizeof(vis) );

79         //memset( fang, -1, sizeof(fang) );

80         //memset( path, 0, sizeof(path) );

81 

82         int ans = dp( 1, 0, -1 );

83         printf( "%d\n", ans );

84     }

85     return 0;

86 }

 

你可能感兴趣的:(over)