题解:
这题怎么也卡常数(自己常数大)
对于是x的位置令x='a'或'c' ('b')
然后用2sat验证即可
问题:缩点版的2sat还不会,貌似效率高
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100009;
int n,m,lim;
int limt[maxn][3];
char limc[maxn][3];
int cntp=0;
int xp[maxn];
char ss[maxn];
int cntedge=0;
int head[maxn];
int to[maxn<<1],nex[maxn<<1];
void Addedge(int x,int y){
nex[++cntedge]=head[x];
to[cntedge]=y;
head[x]=cntedge;
}
int fla[maxn];
int mark[maxn];
char FS(int x){
if(ss[x]=='a')return 'b';
else return 'a';
}
char SE(int x){
if(ss[x]=='a')return 'c';
if(ss[x]=='b')return 'c';
if(ss[x]=='c')return 'b';
}
void Addlims(int i){
int t1=limt[i][1];
int t2=limt[i][2];
char c1=limc[i][1];
char c2=limc[i][2];
if((t1==t2)&&(c1==c2))return;
if(c1==ss[t1])return;
if(c2==ss[t2]){
if(c1==FS(t1))fla[t1*2+1]=1;
else fla[t1*2]=1;
return;
}
int x,y;
if(c1==FS(t1))x=t1*2;
else x=t1*2+1;
if(c2==FS(t2))y=t2*2;
else y=t2*2+1;
Addedge(x,y);
Addedge(y^1,x^1);
}
int Sta[maxn],top;
int Dfs(int x){
if(mark[x^1])return 0;
if(mark[x])return 1;
mark[x]=1;
Sta[++top]=x;
for(int i=head[x];i;i=nex[i]){
if(!Dfs(to[i]))return 0;
}
return 1;
}
int Sol(){
cntedge=0;
memset(fla,0,sizeof(fla));
memset(head,0,sizeof(head));
memset(mark,0,sizeof(mark));
for(int i=1;i<=lim;++i)Addlims(i);
// for(int i=2;i<=n*2+1;++i)cout<<fla[i]<<' ';
// cout<<endl;
for(int i=2;i<=n*2+1;i+=2){
if((!fla[i])&&(!fla[i+1]))continue;
if(fla[i]&&fla[i+1])return 0;
if(fla[i]==1){
if(!Dfs(i))return 0;
}else{
if(!Dfs(i+1))return 0;
}
}
// for(int i=2;i<=n*2+1;++i)cout<<mark[i]<<' ';
// cout<<endl;
for(int i=2;i<=n*2+1;i+=2){
if((!mark[i])&&(!mark[i+1])){
top=0;
if(!Dfs(i)){
while(top){
mark[Sta[top]]=0;--top;
}
if(!Dfs(i+1))return 0;
}
}
}
for(int i=1;i<=n;++i){
if(mark[i*2]){
printf("%c",FS(i)-'a'+'A');
}else{
printf("%c",SE(i)-'a'+'A');
}
}
return 1;
}
int main(){
// freopen("game.in","r",stdin);
// freopen("game.out","w",stdout);
scanf("%d%d",&n,&m);
scanf("%s",ss+1);
for(int i=1;i<=n;++i)if(ss[i]=='x')xp[++cntp]=i;
scanf("%d",&lim);
for(int i=1;i<=lim;++i){
scanf("%d",&limt[i][1]);
limc[i][1]=getchar();
while(limc[i][1]!='A'&&limc[i][1]!='B'&&limc[i][1]!='C')limc[i][1]=getchar();
limc[i][1]=limc[i][1]-'A'+'a';
scanf("%d",&limt[i][2]);
limc[i][2]=getchar();
while(limc[i][2]!='A'&&limc[i][2]!='B'&&limc[i][2]!='C')limc[i][2]=getchar();
limc[i][2]=limc[i][2]-'A'+'a';
}
for(int s=0;s<(1<<m);++s){
for(int i=1;i<=m;++i){
if(s&(1<<(i-1))){
ss[xp[i]]='c';
}else{
ss[xp[i]]='a';
}
}
if(Sol())return 0;
}
cout<<-1<<endl;
return 0;
}