N people form a relationship tree. Each node represents a person. The parent node of the node represents the only boss of the person. Only the root node has no boss. It is required to select a portion of the N people so that no direct upper-lower-level relationship exists between any two people. How many people can be selected at most? Determine whether the optimal solution is unique. If yes, yes. Otherwise, no.
Question: DP [I] [0] indicates the maximum number of people that can be selected from the subtree with the root node when I is not selected; DP [I] [1] indicates that when I is selected, the maximum number of people that can be selected from the subtree with it as the root. Sole [I] [0] indicates whether the optimal solution is unique when I is not selected; sole [I] [1] indicates whether the optimal solution is unique when I is selected.
PS: There are detailed instructions on this PPT http://wenku.baidu.com/view/84164e1a227916888486d7d6.html? From = rec & Pos = 4 & Weight = 1
#include<map>#include<cstring>#include<string>#include<algorithm>#include<iostream>using namespace std;map<string,int> name;map<string,int>::iterator it;int dp[500][2];bool sole[500][2], visit[500];struct Edge { int v, next; } edge[500];int head[500], E, n;void add_edge(int u, int v){ edge[E].v = v; edge[E].next = head[u]; head[u] = E++;}void DFS(int u, int father){ if(visit[u]) return; if(head[u] == -1) { dp[u][0] = 0; dp[u][1] = 1; sole[u][0] = sole[u][1] = true; visit[u] = true; return; } visit[u] = true; dp[u][0] = 0; dp[u][1] = 1; sole[u][0] = sole[u][1] = true; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(v == father) continue; if(!visit[v]) DFS(v, u); dp[u][0] += max(dp[v][0], dp[v][1]); dp[u][1] += dp[v][0]; if(dp[v][0] > dp[v][1] && !sole[v][0]) sole[u][0] = false; if(dp[v][0] < dp[v][1] && !sole[v][1]) sole[u][0] = false; if(dp[v][0] == dp[v][1]) sole[u][0] = false; if(sole[v][0] == false) sole[u][1] = false; }}int main(){ string employee, boss; while(cin >> n) { if(n == 0) break; int i, c, u, v; c = E = 0; memset(head, -1, sizeof(head)); memset(visit, 0, sizeof(visit)); name.clear(); cin >> boss; name.insert(pair<string, int>(boss, 0)); for(i = 1; i < n; i++) { cin >> employee >> boss; it = name.find(employee); if(it == name.end()) { name.insert(pair<string, int>(employee, ++c)); u = c; } else u = it->second; it = name.find(boss); if(it == name.end()) { name.insert(pair<string, int>(boss, ++c)); v = c; } else v = it->second; add_edge(u, v); add_edge(v, u); } DFS(0, -1); if(dp[0][0] > dp[0][1]) cout << dp[0][0] << (sole[0][0] ? " Yes" : " No") << endl; else if(dp[0][0] < dp[0][1]) cout << dp[0][1] << (sole[0][1] ? " Yes" : " No") << endl; else cout << dp[0][0] << " No" << endl; }}