树形dp,用两个量表示每个节点的属性(val正常情况下转移到该节点的值,cost翻转该节点值需要的最少花费),注意叶子节点是无法改变值的,根据儿子节点的状态和其父亲节点表示的是“OR”或“AND”,对应得到花费转移。我们先全部初始化每个节点的花费为INF,最后再判断根节点是不是能够改变(即是否等于INF)即可。
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <deque> 5 #include <stack> 6 #include <cmath> 7 #include <cstdio> 8 #include <vector> 9 #include <string> 10 #include <cstring> 11 #include <fstream> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 #define eps 1e-8 17 #define PI acos(-1.0) 18 #define INF 0x3f3f3f3f 19 #define FAST_IO ios::sync_with_stdio(false) 20 21 const int N=200+10; 22 typedef long long LL; 23 vector <int> E[N]; 24 string s[N]; 25 int c1[N],c2[N]; 26 int cost[N],val[N]; 27 28 void dfs(int u){ 29 if(E[u].size()==0){ 30 if(s[u]=="FALSE") val[u]=0; 31 else val[u]=1; 32 cost[u]=INF; 33 return ; 34 } 35 for(int i=0;i<E[u].size();i++){ 36 int v=E[u][i]; 37 dfs(v); 38 if(val[v]==1) c1[u]++; 39 else c2[u]++; 40 } 41 int mi=INF; 42 for(int i=0;i<E[u].size();i++){ 43 int v=E[u][i]; 44 mi=min(mi,cost[v]); 45 } 46 if(c1[u]&&c2[u]){ 47 if(s[u]=="OR") val[u]=1; 48 else val[u]=0; 49 cost[u]=1; 50 } 51 else{ 52 if(c1[u]) val[u]=1; 53 else val[u]=0; 54 cost[u]=mi; 55 if(cost[u]!=INF){ 56 if(s[u]=="OR"&&c1[u]) cost[u]++; 57 if(s[u]=="AND"&&c2[u]) cost[u]++; 58 } 59 } 60 } 61 62 int main(){ 63 int n,st,u; 64 cin>>n; 65 for(int i=1;i<=n;i++){ 66 cin>>u>>s[i]; 67 if(u==0) st=i; 68 E[u].push_back(i); 69 } 70 for(int i=1;i<=n;i++) cost[i]=INF; 71 dfs(st); 72 if(cost[st]==INF) cout<<-1<<endl; 73 else cout<<cost[st]<<endl; 74 return 0; 75 }