树的最大独立集问题
d(u,0) 表示以u为根的子树中,不选u点能得到的最大人数 f(u,0)=1表示唯一,否则不唯一
d(u,1)--------------------------------选u f(u,1)=1表示唯一,否则不唯一
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 200+5; 5 int n,cnt,d[maxn][2],f[maxn][2]; 6 vector<int> sons[maxn]; 7 map<string,int> dict; 8 9 int ID(string s){ 10 if(!dict.count(s)) dict[s] = cnt++; 11 return dict[s]; 12 } 13 14 int dp(int u,int k){ 15 d[u][k] = k; 16 f[u][k] = 1; 17 for(int i=0; i<sons[u].size(); i++){ 18 int v = sons[u][i]; 19 if(k==1){ 20 d[u][k] += dp(v,0); 21 if(!f[v][0]) f[u][k] = 0; 22 }else{ 23 d[u][k] += max(dp(v,0),dp(v,1)); 24 if(d[v][0]==d[v][1]) f[u][k] = 0; 25 else if(d[v][0]>d[v][1] && !f[v][0]) f[u][k] = 0; 26 else if(d[v][1]>d[v][0] && !f[v][1]) f[u][k] = 0; 27 } 28 } 29 return d[u][k]; 30 31 } 32 33 int main(){ 34 string s,s2; 35 while(cin >> n >> s){ 36 cnt = 0; 37 for(int i=0; i<n; i++) sons[i].clear(); 38 dict.clear(); 39 40 ID(s); 41 for(int i=0; i<n-1; i++){ 42 cin >> s >> s2; 43 sons[ID(s2)].push_back(ID(s)); 44 } 45 int ans; 46 ans = max(dp(0,0),dp(0,1)); 47 printf("%d ", ans); 48 49 bool unique = false; 50 if(d[0][0]>d[0][1] && f[0][0]) unique = true; 51 if(d[0][1]>d[0][0] && f[0][1]) unique = true; 52 53 if(unique) printf("Yes "); 54 else printf("No "); 55 56 } 57 58 }