如果没有x那就是很标准的2-sat模型。
每个点两种选择,上第一种车或第二种,要求i,oi,j,oi就建边i,oi->j,oj,建边j,oj^!->i,oi^1
那对于x怎么办呢?这是3-sat呀qaq还好x的很少,我们可以枚举他为不能上A或不能上B(可以发现,不用枚举不能上C,因为前面的两种情况已经枚举全了)。
复杂度
O(2d(n+m))
O
(
2
d
(
n
+
m
)
)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 50010
inline int read(){
int x=0,f=1;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 x*f;
}
int n,D,pos[10],m,tot=-1,h[N<<1],num,id[N][2],dfn[N<<1],low[N<<1],dfnum,scc,bel[N<<1];
char s[N],op[2];bool flag=0,inq[N<<1];
int du[N<<1],col[N<<1],opp[N<<1];
struct node{
int x,opx,y,opy;
}ev[100010];
struct edge{
int fr,to,next;
}data[200010];
inline void add(int x,int y){
data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].fr=x;
}
inline char idto(int x,int op){
if(s[x]=='a') return 'A'+op+1;
if(s[x]=='b') return op?'C':'A';
return 'A'+op;
}
inline int toid(int x,int op){
if(s[x]=='a') return op-1;
if(s[x]=='b') return op?1:0;
return op;
}stack<int>qq;
inline void tarjan(int x){
dfn[x]=low[x]=++dfnum;qq.push(x);inq[x]=1;
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;
if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
else if(inq[y]) low[x]=min(low[x],dfn[y]);
}if(dfn[x]==low[x]){
++scc;while(1){
int y=qq.top();qq.pop();inq[y]=0;
bel[y]=scc;if(y==x) break;
}
}
}
inline void solve(){
memset(h,0,sizeof(h));num=0;
memset(dfn,0,sizeof(dfn));scc=0;dfnum=0;
for(int i=1;i<=m;++i){
int x=ev[i].x,y=ev[i].y;
if(ev[i].opx==s[x]-'a') continue;
int opx=toid(x,ev[i].opx),opy=toid(y,ev[i].opy);
if(ev[i].opy==s[y]-'a') add(id[x][opx],id[x][opx^1]);
else add(id[x][opx],id[y][opy]),add(id[y][opy^1],id[x][opx^1]);
}for(int i=0;i<=tot;++i) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;++i){
if(bel[id[i][0]]==bel[id[i][1]]) return;opp[bel[id[i][0]]]=bel[id[i][1]];
opp[bel[id[i][1]]]=bel[id[i][0]];
}flag=1;
}
void dfs(int x){
if(x==D+1){solve();return;}
s[pos[x]]='a';dfs(x+1);if(flag) return;
s[pos[x]]='b';dfs(x+1);
}
int main(){
// freopen("a.in","r",stdin);
n=read();D=read();scanf("%s",s+1);m=read();
for(int i=1;i<=n;++i) if(s[i]=='x') pos[++pos[0]]=i;
for(int i=1;i<=n;++i) id[i][0]=++tot,id[i][1]=++tot;
for(int i=1;i<=m;++i){
ev[i].x=read();scanf("%s",op+1);ev[i].opx=op[1]-'A';
ev[i].y=read();scanf("%s",op+1);ev[i].opy=op[1]-'A';
}dfs(1);if(!flag){puts("-1");return 0;}
int num1=num;memset(h,0,sizeof(h));num=0;
for(int i=1;i<=num1;++i){
int x=data[i].fr,y=data[i].to;
if(bel[x]!=bel[y]) add(bel[y],bel[x]),du[bel[x]]++;
}queue<int>q;
for(int i=1;i<=scc;++i) if(!du[i]) q.push(i);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;if(--du[y]==0) q.push(y);
}if(col[x]) continue;col[x]=1;col[opp[x]]=2;
}for(int i=1;i<=n;++i){
if(col[bel[id[i][0]]]==1) putchar(idto(i,0));
else putchar(idto(i,1));
}return 0;
}
6.29upd:uoj上需要卡时一下才能过qaq
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 50010
inline int read(){
int x=0,f=1;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 x*f;
}
int n,d=0,m,id[N][3],pos[10],tot,h[N<<1],num,dfn[N<<1],low[N<<1],dfnum,scc,bel[N<<1],du[N<<1],opp[N<<1];
bool inq[N<<1];int vis[N<<1];
char s[N];
struct Edge{
int x,x1,y,y1;
}e[N<<1];
struct edge{
int to,next,fr;
}data[N<<2];
inline void add(int x,int y){
data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].fr=x;
}
stack<int>qq;
inline void tarjan(int x){
dfn[x]=low[x]=++dfnum;qq.push(x);inq[x]=1;
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;
if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
else if(inq[y]) low[x]=min(low[x],dfn[y]);
}if(low[x]==dfn[x]){
++scc;while(1){
int y=qq.top();qq.pop();inq[y]=0;
bel[y]=scc;if(y==x) break;
}
}
}
inline bool solve(){
tot=1;num=0;memset(h,0,sizeof(h));memset(dfn,0,sizeof(dfn));dfnum=0;scc=0;memset(du,0,sizeof(du));memset(vis,0,sizeof(vis));
for(int i=1;i<=n;++i)
for(int j=0;j<3;++j)
if(j!=s[i]-'a') id[i][j]=++tot;
for(int i=1;i<=m;++i){
if(e[i].x1==s[e[i].x]-'a') continue;
if(e[i].y1==s[e[i].y]-'a'){add(id[e[i].x][e[i].x1],id[e[i].x][e[i].x1]^1);continue;}
add(id[e[i].x][e[i].x1],id[e[i].y][e[i].y1]);
add(id[e[i].y][e[i].y1]^1,id[e[i].x][e[i].x1]^1);
}for(int i=2;i<=tot;++i) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;++i){
if(bel[i<<1]==bel[i<<1|1]) return 0;
opp[bel[i<<1]]=bel[i<<1|1];opp[bel[i<<1|1]]=bel[i<<1];
}int numm=num;num=0;memset(h,0,sizeof(h));
for(int i=1;i<=numm;++i){
int x=data[i].fr,y=data[i].to;
if(bel[x]!=bel[y]) add(bel[y],bel[x]),du[bel[x]]++;
}queue<int>q;
for(int i=1;i<=scc;++i) if(!du[i]) q.push(i);
while(!q.empty()){
int x=q.front();q.pop();if(vis[x]) continue;
vis[x]=1;vis[opp[x]]=2;
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;if(--du[y]==0) q.push(y);
}
}for(int i=1;i<=n;++i)
for(int j=0;j<3;++j){
if(j==s[i]-'a') continue;
if(vis[bel[id[i][j]]]==1) putchar('A'+j);
}puts("");return 1;
}
inline bool dfs(int lev){
if(lev>d) return solve();
if((double)clock()/CLOCKS_PER_SEC>0.8){puts("-1");exit(0);}
s[pos[lev]]='a';if(dfs(lev+1)) return 1;
s[pos[lev]]='b';if(dfs(lev+1)) return 1;
return 0;
}
int main(){
// freopen("game2.in","r",stdin);
n=read();read();scanf("%s",s+1);
for(int i=1;i<=n;++i) if(s[i]=='x') pos[++d]=i;
m=read();for(int i=1;i<=m;++i){
e[i].x=read();char op[2];scanf("%s",op);e[i].x1=op[0]-'A';
e[i].y=read();scanf("%s",op);e[i].y1=op[0]-'A';
}if(!dfs(1)) puts("-1");
return 0;
}