1. 程式人生 > >HDU - 1054 Strategic Game (樹型DP)

HDU - 1054 Strategic Game (樹型DP)

Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to put the minimum number of soldiers on the nodes so that they can observe all the edges. Can you help him?

Your program should find the minimum number of soldiers that Bob has to put for a given tree.

The input file contains several data sets in text format. Each data set represents a tree with the following description:

the number of nodes
the description of each node in the following format
node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifier
or
node_identifier:(0)

The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500). Every edge appears only once in the input data.

For example for the tree:



the solution is one soldier ( at the node 1).

The output should be printed on the standard output. For each given input data set, print one integer number in a single line that gives the result (the minimum number of soldiers). An example is given in the following table:

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)

Output

1
2

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過了一遍,二分圖也過了一遍,但是想了一組樣例:

6
0:(1) 1
1:(1) 2
2:(1) 3
3:(1) 4
4:(1) 5
5:(0)

這個樣例的答案應該是2,但是樹形DP和二分圖的程式碼都是3,網上試了幾個程式碼也都是3。感覺程式碼有點問題,感覺自己不會了(生無可戀中.......)。先放著,如果有大神路過的話幫忙告訴一下我正解(萬分感謝),如果沒有就等我那天開竅了在回來看。

假裝這是個正確程式碼(反正它能AC):

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>q[1510];
int n,dp[1510][3],x,y,m,head[1510],root,book[1510];
int dfs(int u)
{
    book[u]=1;
    int tem,len=q[u].size();
    for(int i=0; i<len; i++)
    {
        tem=q[u][i];
        if(!book[tem])
        {
            dfs(tem);
            dp[u][1]+=min(dp[tem][0],min(dp[tem][1],dp[tem][2]));
            dp[u][0]+=
        }

    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(book,0,sizeof(book));
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=n; i++)
            q[i].clear();
        for(int i=0; i<n; i++)
        {
            dp[i][1]=1;
            scanf("%d:(%d)",&x,&m);
            for(int j=1; j<=m; j++)
            {
                scanf("%d",&y);
                head[x]++;
                q[y].push_back(x);
                q[x].push_back(y);
            }
        }
        for(int i=1; i<=n; i++)
        {
            if(head[i]==0)
            {
                root=i;
                break;
            }
        }
        dfs(root);
        printf("%d\n",min(dp[root][0],dp[root][1]));
    }
}