和poj2342同樣,只是加了判斷最大值是否惟一。ios
當dp2【s】>=dp1【s】時,若dp1【x】==dp2【x】;則不惟一。由於父節點不去更優。兒子節點去和不去都同樣。結果就不惟一了。ide
特殊考慮的是根節點,若是dp1【root】==dp2【root】 ,則不惟一,由於已經到根節點,不影響其餘的點了。spa
此題還能夠建單向邊,由於給定的條件是老闆在後面,code
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<vector> 5 #include<string> 6 #include<map> 7 using namespace std; 8 vector<int>V[220]; 9 map<string,int>M; 10 int vis[220]; 11 int dp1[220];//去 12 int dp2[220];//不去 13 void init() 14 { 15 for(int i=0;i<220;i++) 16 V[i].clear(),dp1[i]=1; 17 memset(dp2,0,sizeof(dp2)); 18 memset(vis,0,sizeof(vis)); 19 M.clear(); 20 } 21 void dfs(int s) 22 { 23 vis[s]=1; 24 for(int i=0;i<(int)V[s].size();i++) 25 { 26 int x=V[s][i]; 27 if(!vis[x]) 28 { 29 dfs(x); 30 dp1[s]+=dp2[x]; //s去,則x不去。 31 dp2[s]+=max(dp1[x] , dp2[x]); //s不去,則在s點加上x去或不去的最大值. 32 //printf("dp1[%d]=%d dp2[%d]=%d\n",s,dp1[s],s,dp2[s]); 33 } 34 } 35 } 36 int main() 37 { 38 //freopen("Input.txt","r",stdin); 39 int n,i; 40 while(scanf("%d",&n)&&n) 41 { 42 init(); 43 string str1,str2; 44 int num=1; 45 cin>>str1; 46 M[str1]=num++; 47 for(i=1;i<n;i++) 48 { 49 cin>>str1>>str2; 50 if(!M[str1]) M[str1]=num++; 51 if(!M[str2]) M[str2]=num++; 52 V[M[str1]].push_back(M[str2]); 53 V[M[str2]].push_back(M[str1]); 54 } 55 dfs(1); 56 printf("%d ",max(dp1[1],dp2[1])); 57 bool flag=true; 58 for(i=1;i<=n;i++) 59 { 60 flag=true; 61 if(dp2[i]>=dp1[i]) 62 { 63 for(int j=0;j<(int)V[i].size();j++) 64 { 65 int x=V[i][j]; 66 if(dp2[x]==dp1[x]) 67 { 68 flag=false; 69 break; 70 } 71 } 72 } 73 if(!flag) break; 74 } 75 if(dp2[1]==dp1[1]||!flag) puts("No"); 76 else puts("Yes"); 77 // puts("--------------------------------"); 78 // for(i=1;i<=n;i++) 79 // printf("%d %d\n",dp1[i],dp2[i]); 80 } 81 return 0; 82 }