树状的动态规划
#include <stdio.h>
#include <list>
#include <vector>
using namespace std;
vector<int> tree[2000];
int record[2000][2];
#define SET_SOLDIER 1
#define NO_SOLDIER 0
int _min(int a, int b){
return a<b ? a:b;
}
int get_value(int root, int soldier){
int sum;
if(-1 != record[root][soldier]){
return record[root][soldier];
}
if(tree[root].empty()){
record[root][soldier] = soldier;
return soldier;
}
if(soldier){
sum = 0;
for(int i=0; i<tree[root].size(); i++){
sum += _min(get_value(tree[root][i], SET_SOLDIER), get_value(tree[root][i], NO_SOLDIER));
}
record[root][soldier] = sum+1;
return sum+1;
}
else{
sum = 0;
for(int i=0; i<tree[root].size(); i++){
sum += get_value(tree[root][i], SET_SOLDIER);
}
record[root][soldier] = sum;
return sum;
}
}
void func(int root){
printf("%d\n", _min(get_value(root, SET_SOLDIER), get_value(root, NO_SOLDIER)));
}
int main(void){
int n, i, j, path_n, root, son;
int tree_root;
//freopen("input.dat", "r", stdin);
while(~scanf("%d", &n)){
for(i=0; i<n; i++){
tree[i].clear();
record[i][0] = record[i][1] = -1;
}
for(i=0; i<n; i++){
scanf("%d:(%d)", &root, &path_n);
if(0 == i) tree_root = root;
for(j=0; j<path_n; j++){
scanf("%d", &son);
tree[root].push_back(son);
if(son == tree_root)
tree_root = root;
}
}
func(tree_root);
}
return 0;
}