题目大意:对于一个不完全二分图,根节点为1,叶节点值为0或1,非叶节点包含一个操作(and,or,xor,not),求改变各个叶节点的值时(即0改为1,1改为0),根节点的值是多少
解法:遍历图求各节点的值,改变每个叶节点时,向图根节点遍历,求根节点值即可
有两个需要剪枝的地方,一,当改变到当前节点是该节点值已经不在改变,则结束图的向上递归
二,维护每个节点改变时,根节点的值,当再次遍历次节点时,可直接得到答案,结束递归
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<queue> 5 #include<vector> 6 #include<string.h> 7 #include<cstring> 8 #include<algorithm> 9 #include<set> 10 #include<map> 11 #include<fstream> 12 #include<cstdlib> 13 #include<ctime> 14 using namespace std; 15 #define scd(a) scanf("%d",&a) 16 #define scf(a) scanf("%lf",&a) 17 #define scl(a) scanf("%lld",&a) 18 #define sci(a) scanf("%I64d",&a) 19 #define scs(a) scanf("%s",a) 20 typedef long long ll; 21 const int desll[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; 22 const ll mod=1e9+7; 23 const int maxn=1e6+7; 24 const int maxm=1e8+7; 25 const double eps=1e-4; 26 int m,n,ar[maxn]; 27 char ch[maxn]; 28 int armid[maxn]; 29 struct node{ 30 int val,num; 31 char c; 32 node *pre,*l,*r; 33 void clear(){ 34 l=r=NULL; 35 } 36 }no[maxn]; 37 int ma,ans=0; 38 int newCal(node* u)//求此节点的新值 39 { 40 if(u->c=='N') return 1-(u->l->val); 41 else if(u->c=='A') return u->l->val & u->r->val; 42 else if(u->c=='X') return u->l->val ^ u->r->val; 43 else if(u->c=='O') return u->l->val | u->r->val; 44 } 45 void dfs(node* u,int x) 46 { 47 int now=u->val; 48 u->val=x; 49 if(u->pre == NULL || now == x){//若此节点为根节点或此节点值已经不在改变,结束递归 50 ma=1; 51 ans=no[1].val; 52 } 53 else{ 54 if(armid[u->num]!=-1){//若此节点之前已经被便利过,则直接输出 55 ans = armid[u->num];//armid维护每个节点值改变时引起的根节点改变之后的值 56 ma=1; 57 } 58 else{ 59 dfs(u->pre,newCal(u->pre)); 60 armid[u->num]=ans; 61 } 62 } 63 u->val=now; 64 } 65 66 void init(node* u) 67 { 68 //cout<<u->val<<endl; 69 if(u->c=='I')return ; 70 init(u->l); 71 if(u->r!=NULL)init(u->r); 72 if(u->c=='N')u->val=1-(u->l->val); 73 else if(u->c=='A')u->val = u->l->val & u->r->val; 74 else if(u->c=='X')u->val = u->l->val ^ u->r->val; 75 else if(u->c=='O')u->val = u->l->val | u->r->val; 76 } 77 int main() 78 { 79 scd(n); 80 int x,y; 81 no[1].pre=NULL; 82 for(int i=0;i<=n;i++)no[i].clear(); 83 for(int i=1;i<=n;i++){ 84 scs(ch);scd(x); 85 if(ch[0]=='A' || ch[0]=='O' || ch[0]=='X'){ 86 scd(y); 87 no[i].l=&no[x]; 88 no[i].r=&no[y]; 89 no[x].pre = &no[i]; 90 no[y].pre = &no[i]; 91 no[i].c=ch[0]; 92 } 93 else if(ch[0]=='N'){ 94 no[i].l= &no[x]; 95 no[x].pre = &no[i]; 96 no[i].c=ch[0]; 97 } 98 else{ 99 no[i].val=x; 100 no[i].c=ch[0]; 101 } 102 no[i].num=i; 103 } 104 memset(armid,-1,sizeof(armid)); 105 init(&no[1]); 106 int len=0; 107 for(int i=1;i<=n;i++){ 108 ma=0; 109 if(no[i].c=='I'){ 110 dfs(&no[i],1-no[i].val); 111 ar[len++]=ans; 112 } 113 } 114 for(int i=0;i<len;i++){ 115 printf("%d",ar[i]); 116 } 117 printf(" "); 118 119 120 return 0; 121 }