Consider plain search. For each node on the tree, the state is only selected or not selected.
And it is obvious: if the current node is selected, the child node can be selected or not; and if the current node is not selected, the child node must be selected.
It is easy to see that the search trees thus generated will have a lot of overlap. So consider memoized search.
Use an array d[cur][2] to record the search results of the current node selected (d[cur][1]) or not selected (d[cur][0]).
Ultimately, the time complexity is O(n) level.
Code below:
1 #include <cstdio> 2 #include <iostream> 3 #include <vector> 4 #include <cstring> 5 using namespace std; 6 const int MAXN = 1500 + 20; 7 const int INF = 0x7f7f7f7f; 8 9 inline int read() 10 { 11 int x = 0; char ch = getchar(); 12 while(!isdigit(ch)) ch = getchar(); 13 while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); 14 return x; 15 } 16 17 int N; 18 vector<int> g[MAXN]; 19 int d[MAXN][2]; 20 21 inline void clean() 22 { 23 for(int i = 0; i <= N; i++) 24 g[i].clear(); 25 memset(d, 0x7f, sizeof(d)); 26 } 27 28 int dfs(int cur, bool opt, int fa) 29 { 30 if(g[cur].size() == 1 && g[cur][0] == fa) 31 return opt; 32 33 int ans = 0; 34 if(!opt) 35 { 36 for(int i = 0; i < (int) g[cur].size(); i++) 37 { 38 int v = g[cur][i]; 39 if(v != fa) 40 { 41 if(d[v][true] == INF) d[v][true] = dfs(v, true, cur); 42 ans += d[v][true]; 43 } 44 } 45 } 46 else 47 { 48 for(int i = 0; i < (int) g[cur].size(); i++) 49 { 50 int v = g[cur][i]; 51 if(v != fa) 52 { 53 if(d[v][true] == INF) d[v][true] = dfs(v, true, cur); 54 if(d[v][false] == INF) d[v][false] = dfs(v, false, cur); 55 ans += min(d[v][false], d[v][true]); 56 } 57 } 58 ans++; 59 } 60 return ans; 61 } 62 63 inline void solve() 64 { 65 cout<<min(dfs(0, true, 0), dfs(0, false, 0))<<endl; 66 } 67 68 int main() 69 { 70 //freopen("1292.txt", "r", stdin); 71 while(cin>>N) 72 { 73 clean(); 74 int u, v, c; 75 for(int i = 1; i <= N; i++) 76 { 77 u = read(), c = read(); 78 for(int j = 1; j <= c; j++) 79 { 80 v = read(); 81 g[u].push_back(v); 82 g[v].push_back(u); 83 } 84 } 85 solve(); 86 } 87 return 0; 88 }