树状dp。必要条件:子树之间不可以相互干扰。 思路来源于ppt.发现上午的程序有bug,现改正了下。 时间由15ms变为了0ms。原来判断语句也是很浪费时间的! #include<iostream> #include<cstdio> #include<cstring> using namespace std; int head[210]; char name1[110],name2[110]; char name[210][110]; int cnt,len; int max(int a,int b) { return a>b?a:b;} class node { public: int v,yes,no; bool yessole,nosole; bool tt; bool vis; int next; node() { tt=true;vis=false; yes=1;no=0; yessole=true;nosole=true; } }; int research(char a[]) { for(int i=1;i<=cnt;i++) if(strcmp(a,name[i])==0) return i; cnt++; strcpy(name[cnt],a); return cnt; } void add(int son,int father,node g[]) { g[++len].v =son; g[len].tt=false; g[len].next =head[father]; head[father]=len; } void DP(int root,node g[]) { g[root].vis =true; int i,r1=0,r0; for(i=head[root];i;i=g[i].next ) { int v=g[i].v ; if(!g[v].vis) DP(v,g); r1+=g[v].no ; if(g[v].nosole ==false) g[root].yessole =false; g[root].no +=max(g[v].yes ,g[v].no ); if(g[v].yes ==g[v].no ||(g[v].no>g[v].yes &&g[v].nosole ==false)||(g[v].yes >g[v].no &&g[v].yessole ==false)) g[root].nosole =false; } g[root].yes =r1+1; } int main() { int n; while(1) { cin>>n; if(n==0) break; cnt=1; len=0; node g[10005]; memset(head,0,sizeof(head)); scanf("%s",&name1); strcpy(name[1] ,name1 ); for(int i=1;i<n;i++) { scanf("%s%s",&name1,&name2); int f1=research(name1); int f2=research(name2); add(f1,f2,g); } DP(1,g); if(g[1].no >g[1].yes ) { printf("%d ",g[1].no ); if(g[1].nosole ) printf("Yes/n"); else printf("No/n"); } else if(g[1].no ==g[1].yes ){ printf("%d No/n",g[1].yes ); } else { printf("%d ",g[1].yes ); if(g[1].yessole ) printf("Yes/n"); else printf("No/n"); } } return 0; }