题解:
这题怎么也卡常数(自己常数大)
对于是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; }