POJ 1694 ancient game | greed | tree DP

Description

  There is an old stone game, the game is based on any of a tree T, the game's goal is to put a stone on the root of the tree T, the rules of the game are as follows:

  1, before the start of the game, the player first K stones into the bucket.
  2, at each step of the game, players take a stone placed on an empty leaf node of the tree from the bucket.
  3, when all child nodes of a node p r has a stone, the stone removing child nodes r, then a stone onto the node p. R-1 remaining stones reused again into the tub.

  If a player places a stone in accordance with the above rules, and finally placed a stone on the head node, it wins the game. Now the task is to find the beginning of the game, the minimum number of stone K, so that players can win the game in the case of a given tree.

Input

  The first row of the number of test input T, a tree is a description of each test case. Described in the second line input of each tree. Each tree has N nodes, nodes numbered 1,2, ... N, each node can have any child nodes, the root node numbered 1. Describes the behavior of the first tree of nodes N, the second line descriptor node N nodes according to the order of node labels, each label row is the first number p, the second number of sub-nodes r, if r is not 0, then r is the child node labels.

Output

  , The minimum number of outputs of each tree stone.

Sample Input 1

2
7
1 2 2 3
2 2 5 4
3 2 6 7
4 0
5 0
6 0
7 0
12
1 3 2 3 4
2 0
3 2 5 6
4 3 7 8 9
5 3 10 11 12
6 0
7 0
8 0
9 0
10 0
11 0
12 0

Sample Output 1

3
4

Hint

1<=T<=100,1<=N<=1000


Greedy thinking, start with the largest demand for one child, each child node can have up to -1 demand remaining stone, if the stone is not enough demand remaining before the current sub-node on the number of filled to demand.

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include<algorithm>
#include<vector>
#define inf 0x3f3f3f3f
#define maxn 1005
#define maxm 1005
#define mo 3153600
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rof(i,a,b) for(int i=(a);i>(b);--i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
#define _per(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
int fir[maxn],ne[maxm],to[maxm],np=0;
void add(int x,int y){
    ne[++np]=fir[x];
    fir[x]=np;
    to[np]=y;
}
int dp[maxn];
void dfs(int u){
    if(!fir[u]){
        dp[u]=1;
        return;
    }
    int cnt=0,tmp[maxn];
    for(int i=fir[u];i;i=ne[i]){
        int v=to[i];
        dfs(v);
        tmp[++cnt]=dp[v];
    }
    sort(tmp+1,tmp+1+cnt,greater<int>());
    dp[u]=0;
    for(int i=1,re=0;i<=cnt;i++,re--){
        if(tmp[i]>re){
            dp[u]+=(tmp[i]-re);
            re=tmp[i];
        }
    }
    return;
}
int n;
void init(){
    memset(fir,0,sizeof fir);
    np=0;
    scanf("%d",&n);
    _rep(i,1,n){
        int x,y,k;
        scanf("%d%d",&x,&k);
        while(k--){
            scanf("%d",&y);
            add(x,y);
        }
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        init();
        dfs(1);
        printf("%d\n",dp[1]);
    }
    return 0; 
}

Guess you like

Origin www.cnblogs.com/de-compass/p/11248252.html