hdu 1054 Strategic Game

题意:给你一颗树,然后在数的结点上进行标记,一个结点被标记之后,连接它的边也被标记,最少标记几个点可以把所有的边标记。

思路:树形dp,和刘汝佳白书70页放置街灯一样。dp[u][1]表示在u结点标记,dp[u][0]表示在u结点不标记。

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <vector>

 4 #include <cmath>

 5 #include <algorithm>

 6 #define maxn 100010

 7 using namespace std;

 8 

 9 int n,m;

10 vector<int>g[maxn];

11 int dp[maxn][2];

12 

13 int dfs(int u,int c,int fa)

14 {

15     if(dp[u][c]>=0) return dp[u][c];

16     int &ans=dp[u][c];

17     ans=2000;

18     for(int i=0; i<(int)g[u].size(); i++)

19     {

20         int v1=g[u][i];

21         if(v1!=fa)

22         ans+=dfs(v1,1,u);

23     }

24     if(c==1||fa==-1)

25     {

26         int sum=0;

27         for(int i=0; i<(int)g[u].size(); i++)

28         {

29             int v=g[u][i];

30             if(v!=fa)

31             {

32                 sum+=dfs(v,0,u);

33                 sum++;

34             }

35         }

36         if(fa>=0) sum++;

37         ans=min(ans,sum);

38     }

39     return ans;

40 }

41 

42 int main()

43 {

44     while(scanf("%d",&n)!=EOF)

45     {

46         for(int i=0; i<=n; i++)

47         {

48             g[i].clear();

49         }

50         for(int i=1; i<=n; i++)

51         {

52             int u,cnt,v;

53             scanf("%d:(%d)",&u,&cnt);

54             while(cnt--)

55             {

56                 scanf("%d",&v);

57                 g[u].push_back(v);

58                 g[v].push_back(u);

59             }

60         }

61         int ans=0;

62         memset(dp,-1,sizeof(dp));

63         for(int i=0; i<n; i++)

64         {

65             if(dp[i][1]==-1) ans+=dfs(i,0,-1);

66         }

67         printf("%d\n",ans/2000);

68     }

69     return 0;

70 }
View Code

 

你可能感兴趣的:(game)