嘟嘟嘟
這題也太暴力了……
考慮若是沒有'x'的狀況,那就是2-SAT水題。有了'x'怎麼辦?由於'x'最多隻有8個,因此咱們暴力枚舉,時間複雜度\(O((n + m) * 3 ^ 8)\)。這算出來後大約是\(9e8\),因此就沒敢寫……
然而這實際上根本跑不滿,找到合法的就exit(0)
,幾乎每個點不到200ms就跑出來了……
不過有一個地方仍是要講一下的,就是若是賽道\(i\)選了\(h_i\)車,則\(j\)就得選\(h_j\)。首先若是\(h_i\)不存在,不連邊;若是\(h_j\)不存在。連邊\(i -> i'\),表示選了\(i\)就gg;不然要連兩條邊,分別是\(i->j\)和\(j' ->i'\),剛開始我以爲第二條不用連,畢竟選\(h_j\)不選\(h_i\)是能夠的。但咱們得考慮2-SAT的對稱性,即若是\(j\)不選\(h_j\),則\(i\)只能選除\(h_i\)以外的另外一輛。ios
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> #include<cctype> #include<vector> #include<stack> #include<queue> using namespace std; #define enter puts("") #define space putchar(' ') #define Mem(a, x) memset(a, x, sizeof(a)) #define In inline typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxn = 5e4 + 5; const int maxe = 4e5 + 5; inline ll read() { ll ans = 0; char ch = getchar(), last = ' '; while(!isdigit(ch)) last = ch, ch = getchar(); while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); if(last == '-') ans = -ans; return ans; } inline void write(ll x) { if(x < 0) x = -x, putchar('-'); if(x >= 10) write(x / 10); putchar(x % 10 + '0'); } In void MYFILE() { #ifndef mrclr freopen("game.in", "r", stdin); freopen("game.out", "w", stdout); #endif } char s[maxn], c1[2], c2[2], asc[maxn << 1]; int n, d, m; struct Node { int x; char c1; int y; char c2; }q[maxn << 1]; int h[maxn][3], a[maxn], cnt = 0; In void init() { for(int i = 1; i <= n; ++i) { if(s[i] == 'x') a[++cnt] = i; else if(s[i] == 'a') h[i][1] = i, h[i][2] = n + i, asc[i] = 'B', asc[i + n] = 'C'; else if(s[i] == 'b') h[i][0] = i, h[i][2] = n + i, asc[i] = 'A', asc[i + n] = 'C'; else if(s[i] == 'c') h[i][0] = i, h[i][1] = n + i, asc[i] = 'A', asc[i + n] = 'B'; } } struct Edge { int nxt, to; }e[maxe]; int head[maxn << 1], ecnt = -1; In void addEdge(int x, int y) { e[++ecnt] = (Edge){head[x], y}; head[x] = ecnt; } bool in[maxn << 1]; int st[maxn << 1], top = 0; int dfn[maxn << 1], low[maxn << 1], dcnt = 0; int col[maxn << 1], ccol = 0; In void tarjan(int now) { st[++top] = now; in[now] = 1; dfn[now] = low[now] = ++dcnt; for(int i = head[now], v; ~i; i = e[i].nxt) { if(!dfn[v = e[i].to]) { tarjan(v); low[now] = min(low[now], low[v]); } else if(in[v]) low[now] = min(low[now], dfn[v]); } if(low[now] == dfn[now]) { int x; ++ccol; do { x = st[top--]; in[x] = 0; col[x] = ccol; }while(x ^ now); } } In void build() { for(int i = 1; i <= m; ++i) { int u = h[q[i].x][q[i].c1 - 'A'], v = h[q[i].y][q[i].c2 - 'A']; if(!u) continue; if(!v) addEdge(u, u > n ? u - n : u + n); else addEdge(u, v), addEdge(v > n ? v - n : v + n, u > n ? u - n : u + n); } } In void clear() { ecnt = -1; top = dcnt = ccol = 0; Mem(head, -1), Mem(dfn, 0), Mem(low, 0), Mem(in, 0); } In bool check() { clear(), build(); for(int i = 1; i <= (n << 1); ++i) if(!dfn[i]) tarjan(i); for(int i = 1; i <= n; ++i) if(col[i] == col[i + n]) return 0; return 1; } In void print() { for(int i = 1; i <= n; ++i) putchar(col[i] < col[i + n] ? asc[i] : asc[i + n]); enter; } In void dfs_bf(int now) { if(now == cnt + 1) { if(check()) print(), exit(0); return; } for(int i = 0; i < 3; ++i) { h[a[now]][(i + 2) % 3] = a[now], asc[a[now]] = 'A' + (i + 2) % 3; h[a[now]][(i + 1) % 3] = a[now] + n, asc[a[now] + n] = 'A' + (i + 1) % 3; h[a[now]][i] = 0; dfs_bf(now + 1); } } int main() { MYFILE(); Mem(head, -1); n = read(), d = read(); scanf("%s", s + 1); m = read(); for(int i = 1; i <= m; ++i) { int x = read(); scanf("%s", c1); int y = read(); scanf("%s", c2); q[i] = (Node){x, c1[0], y, c2[0]}; } init(); dfs_bf(1); puts("-1"); return 0; }