暴力枚举每个x可能的三种情况,使每个地图都只有两种可能的取值。对于每一种枚举的方案做2-SAT,如果都没有解则判断为无解。
建图时,对于一个限制条件i hi j hj:如果hi不可用,则不连边;如果hj不可用,则由i场地用hi的点向不用hi的点连边,代表i场地不能用hi;如果都可用,则由i场地用hi的点向j场地用hj的点连边,再由j场地不用hj的点向i场地不用hi的点连边。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010,M=200010;
struct lim{
int x,qx,y,qy;
}l[M>>1];
struct edge{
int y,next;
}data[M];
char str1[N],str2[5];
int n,m,d,num,num1,num2,top,len,cnt;
int acsol[N>>1][3],sol[N],h[N],dfn[N],low[N],sta[N],f[N],akind[10];
bool vis[N],insta[N],flag;
inline int read(){
int x=0,f=0;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return f?-x:x;
}
inline void add(int x,int y){
data[++num].y=y;data[num].next=h[x];h[x]=num;
}
void tarjan(int u){
sta[++top]=u;
insta[u]=vis[u]=true;
dfn[u]=low[u]=++num1;
for(int i=h[u];i!=-1;i=data[i].next){
int v=data[i].y;
if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}
else if(insta[v]&&dfn[v]<low[u])low[u]=dfn[v];
}
if(dfn[u]==low[u]){
++num2;
while(dfn[sta[top]]!=low[sta[top]]){
f[sta[top]]=num2;insta[sta[top--]]=false;
}
f[u]=num2;insta[sta[top--]]=false;
}
}
bool two_sat(){
memset(h,-1,sizeof h);num=num1=num2=top=0;
for(int qx,qy,i=1;i<=m;i++){
qx=l[i].qx;qy=l[i].qy;
if(str1[l[i].x]-'a'==l[i].qx)qx=-1;
if(str1[l[i].y]-'a'==l[i].qy)qy=-1;
if(qx==-1)continue;
if(qy==-1)add(acsol[l[i].x][qx],acsol[l[i].x][qx]^1);
else{
add(acsol[l[i].x][qx],acsol[l[i].y][qy]);
add(acsol[l[i].y][qy]^1,acsol[l[i].x][qx]^1);
}
}
memset(vis,false,sizeof vis);
memset(dfn,0,sizeof dfn);
for(int i=0;i<2*n;i++)if(!vis[i])tarjan(i);
bool flag1=true;
for(int i=0;i<n;i++)if(f[i<<1]==f[i<<1|1]){flag1=false;break;}
return flag1;
}
void dfs(int c,int x){
if(c>d){flag=two_sat();return;}
str1[x]='a';sol[x<<1]=1;sol[x<<1|1]=2;acsol[x][1]=x<<1;acsol[x][2]=x<<1|1;
dfs(c+1,akind[c+1]);if(flag)return;
str1[x]='b';sol[x<<1]=0;sol[x<<1|1]=2;acsol[x][0]=x<<1;acsol[x][2]=x<<1|1;
dfs(c+1,akind[c+1]);if(flag)return;
str1[x]='c';sol[x<<1]=0;sol[x<<1|1]=1;acsol[x][0]=x<<1;acsol[x][1]=x<<1|1;
dfs(c+1,akind[c+1]);if(flag)return;
}
int main(){
n=read();d=read();cnt=0;
scanf("%s",str1);len=strlen(str1);
for(int i=0;i<len;i++){
if(str1[i]=='x')akind[++cnt]=i;
else{
if(str1[i]=='a'){sol[i<<1]=1;sol[i<<1|1]=2;acsol[i][1]=i<<1;acsol[i][2]=i<<1|1;}
else if(str1[i]=='b'){sol[i<<1]=0;sol[i<<1|1]=2;acsol[i][0]=i<<1;acsol[i][2]=i<<1|1;}
else{sol[i<<1]=0;sol[i<<1|1]=1;acsol[i][0]=i<<1;acsol[i][1]=i<<1|1;}
}
}
m=read();
for(int i=1;i<=m;i++){
l[i].x=read()-1;
scanf("%s",str2);
if(str1[l[i].x]-'a'==str2[0]-'A')l[i].qx=-1;
else l[i].qx=str2[0]-'A';
l[i].y=read()-1;
scanf("%s",str2);
if(str1[l[i].y]-'a'==str2[0]-'A')l[i].qy=-1;
else l[i].qy=str2[0]-'A';
}
flag=false;dfs(1,akind[1]);
if(!flag)printf("-1");
else{
for(int i=0;i<n;i++){
if(f[i<<1]<f[i<<1|1])printf("%c",'A'+sol[i<<1]);
else printf("%c",'A'+sol[i<<1|1]);
}
}
return 0;
}