1. 程式人生 > >Party at Hali-Bula(樹形DP+判斷方案數是否唯一)

Party at Hali-Bula(樹形DP+判斷方案數是否唯一)

blank ret algo 以及 scan enter clear return nbsp

Party at Hali-Bula

UVA - 1220

題意:
公司裏有n(n<=200)個人形成一個樹狀結構, 要求盡量選多的人,但不能同時選擇一個人和他的直屬上司,文最多能選多少人,以及是否方案唯一。

  1 //dp[x][0]表示不選X節點能達到的最大人數,dp[x][1]表示選x節點的最大人數 
  2 //f數組含義和dp基本一致,f[x][0]表示如果不選x節點是否方案數唯一 f[x][1]表示如果選x節點方案數是否唯一
  3 //如果f數組為1表示方案數不唯一
  4 //對於一個根節點,如果其子節點中有一個方案數不唯一則其方案數不唯一
  5  
  6 #include<iostream>
  7
#include<cstdio> 8 #include<cstring> 9 #include<map> 10 #include<vector> 11 #include<algorithm> 12 using namespace std; 13 vector<int>v[500]; 14 string s1,s2; 15 map<string,int>mp; 16 int n; 17 int flag; 18 int dp[500][500]; 19 int f[500][500]; 20 int vis[500
]; 21 void dfs(int x) 22 { 23 24 dp[x][0]=0; 25 dp[x][1]=1; 26 vis[x]=1; 27 for(int i=0;i<v[x].size();i++) 28 { 29 int to=v[x][i]; 30 if(vis[to]) 31 continue; 32 dfs(to); 33 //選根節點 34 dp[x][1]+=dp[to][0]; 35
if(f[to][0]) 36 { 37 f[x][1]=1; 38 } 39 //不選根節點 40 if(dp[to][0]>dp[to][1]) 41 { 42 dp[x][0]+=dp[to][0]; 43 if(f[to][0]) 44 { 45 f[x][0]=1; 46 } 47 } 48 else 49 { 50 dp[x][0]+=dp[to][1]; 51 if(f[to][1]||dp[to][0]==dp[to][1]) 52 { 53 f[x][0]=1; 54 } 55 } 56 } 57 return ; 58 } 59 int main() 60 { 61 while(~scanf("%d",&n)&&n) 62 { 63 memset(vis,0,sizeof(vis)); 64 memset(dp,0,sizeof(dp)); 65 memset(f,0,sizeof(f)); 66 for(int i=0;i<500;i++) 67 v[i].clear(); 68 mp.clear(); 69 cin>>s1; 70 int cnt=1; 71 if(!mp[s1]) 72 { 73 mp[s1]=cnt++; 74 } 75 n--; 76 while(n--) 77 { 78 cin>>s1>>s2; 79 if(!mp[s1]) 80 { 81 mp[s1]=cnt++; 82 } 83 if(!mp[s2]) 84 { 85 mp[s2]=cnt++; 86 } 87 v[mp[s2]].push_back(mp[s1]); 88 } 89 flag=0; 90 dfs(1); 91 printf("%d ",max(dp[1][0],dp[1][1])); 92 if(dp[1][0]==dp[1][1]) 93 { 94 puts("No"); 95 } 96 else 97 { 98 if(dp[1][0]>dp[1][1]) 99 { 100 if(f[1][0]) 101 cout<<"No"<<endl; 102 else 103 cout<<"Yes"<<endl; 104 } 105 else if(dp[1][1]>dp[1][0]) 106 { 107 if(f[1][1]) 108 cout<<"No"<<endl; 109 else 110 cout<<"Yes"<<endl; 111 } 112 113 } 114 } 115 }

Party at Hali-Bula(樹形DP+判斷方案數是否唯一)