poj 3342
简单树形DP,父节点要么去要么不去;
res[i]=max(∑res[child[i]],∑res[child(child[i])]);
#include<iostream> #include<cstdio> #include<cstring> using namespace std; struct node { int i,next; }vert[201]; char name[201][20]; int head[201],res[201],go[201],nogo[201],N,count; int find(char * str) { int i; for(i=1;i<N;i++) if(strcmp(name[i],str)==0) return i; strcpy(name[N],str); return N++; } int add(int s,int t) { vert[count].i=t; vert[count].next=head[s]; return count++; } int GetRes(int root) { int j,k,sum1=0,sum2=0; if(head[root]==0) { res[root]=1; go[root]=1; nogo[root]=0; return res[root]; } for(j=head[root];j;j=vert[j].next) { sum1+=GetRes(vert[j].i); for(k=head[vert[j].i];k;k=vert[k].next) sum2+=res[vert[k].i]; } go[root]=sum1; nogo[root]=sum2+1; res[root]=go[root] > nogo[root] ? go[root] : nogo[root]; return res[root]; } int judge(int root) { int j,k; if(head[root]==0) return 1; if(go[root]==nogo[root]) return 0; if(go[root]>nogo[root]) { for(j=head[root];j;j=vert[j].next) if(!judge(vert[j].i)) return 0; } else { for(j=head[root];j;j=vert[j].next) for(k=head[vert[j].i];k;k=vert[k].next) if(!judge(vert[k].i)) return 0; } return 1; } int main() { int i,k,n,s,t; char str1[20],str2[20]; while(scanf("%d",&n) && n) { N=count=1; memset(head,0,sizeof(head)); scanf("%s",str1); k=find(str1); for(i=1;i<n;i++) { scanf("%s %s",str1,str2); s=find(str1); t=find(str2); head[t]=add(t,s); } printf("%d ",GetRes(k)); if(judge(k)) printf("Yes\n"); else printf("No\n"); } return 0; }