第一眼看上去似乎是一个3-SAT问题
然而\(d \leq 8\)给我们的信息就是:暴力枚举
枚举\(x\)型地图变成\(a\)型地图还是\(b\)型地图(实际上不要枚举\(c\),因为\(ab\)两种地图已经包含了选择\(ABC\)三辆车的情况),对于每一种情况跑2-SAT即可。复杂度\(O(2^d(n+m))\)
还有为什么UOJ的Hack那么强啊QAQ
随机化要么WA EX5要么WA EX8,不随机化TLE EX9
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c)){
if(c == '-')
f = 1;
c = getchar();
}
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
}
const int MAXN = 2e5 + 3 , T = 190;
struct Edge{
int end , upEd;
}Ed[MAXN << 1];
int head[MAXN] , dfn[MAXN] , low[MAXN] , in[MAXN] , st[MAXN] , ban[MAXN];
int cntEd , top , ts , cntX , N , M , scc , x[9] , ys[MAXN][4];
char s[MAXN];
bool ins[MAXN];
inline void addEd(int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
}
inline char getc(){
char c = getchar();
while(!islower(c))
return c;
return c;
}
void tarjan(int x){
dfn[x] = low[x] = ++ts;
ins[x] = 1;
st[++top] = x;
for(int i = head[x] ; i ; i = Ed[i].upEd){
if(!dfn[Ed[i].end])
tarjan(Ed[i].end);
else
if(!ins[Ed[i].end])
continue;
low[x] = min(low[x] , low[Ed[i].end]);
}
if(dfn[x] == low[x]){
++scc;
do{
ins[st[top]] = 0;
in[st[top]] = scc;
}while(st[top--] != x);
}
}
#define calc(ys , p) ((ys) + ((p) == 2 - (ban[ys] == 2)) * N)
bool solve(){
memset(dfn , 0 , sizeof(int) * (N * 2 + 1));
memset(head , 0 , sizeof(int) * (N * 2 + 1));
cntEd = ts = scc = 0;
for(int i = 1 ; i <= M ; ++i){
if(ban[ys[i][0]] == ys[i][1])
continue;
if(ban[ys[i][2]] == ys[i][3]){
addEd(calc(ys[i][0] , ys[i][1]) , calc(ys[i][0] , 3 - ban[ys[i][0]] - ys[i][1]));
continue;
}
int p = calc(ys[i][0] , ys[i][1]) , q = calc(ys[i][2] , ys[i][3]);
addEd(p , q);
addEd(q + (q > N ? -N : N) , p + (p > N ? -N : N));
}
for(int i = 1 ; i <= N * 2 ; ++i)
if(!dfn[i])
tarjan(i);
for(int i = 1 ; i <= N ; ++i)
if(in[i] == in[i + N])
return 0;
return 1;
}
deque < int > q;
int main(){
#ifndef ONLINE_JUDGE
//freopen("in" , "r" , stdin);
//freopen("out" , "w" , stdout);
#endif
srand((unsigned)time(0));
N = read();
read();
scanf("%s" , s + 1);
for(int i = 1 ; i <= N ; ++i)
if(s[i] == 'x')
x[cntX++] = i;
else
ban[i] = s[i] - 'a';
M = read();
for(int i = 1 ; i <= M ; ++i){
ys[i][0] = read();
ys[i][1] = getc() - 'A';
ys[i][2] = read();
ys[i][3] = getc() - 'A';
}
for(int i = 0 ; i < 1 << cntX ; ++i)
q.push_back(i);
srand((unsigned)time(0));
random_shuffle(q.begin() , q.end());
for(int i = T ; i >= 0 && !q.empty() ; --i){
int t = q.front();
q.pop_front();
random_shuffle(q.begin() , q.end());
for(int j = 0 ; j < cntX ; ++j)
ban[x[j]] = (bool)(t & (1 << j));
if(solve()){
for(int j = 1 ; j <= N ; ++j)
switch(ban[j]){
case 0:
putchar('B' + (in[j] > in[j + N]));
break;
case 1:
putchar('A' + (in[j] > in[j + N]) * 2);
break;
case 2:
putchar('A' + (in[j] > in[j + N]));
}
return 0;
}
}
printf("-1");
return 0;
}