【LOJ】 #2305. 「NOI2017」游戏

题解

枚举x所在的地图的颜色,然后2-SAT建边

如果v所在的地图刚好是不能选的,那么u这边只能选另一种颜色

否则就是u的颜色到v的颜色

v的另一种颜色到u的另一种颜色

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
//#define ivorysi
#define MAXN 100005
#define eps 1e-7
#define mo 974711
#define pb push_back
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
int N,D,M;
char s[MAXN],c[2][MAXN][4],L[MAXN];
int u[MAXN],v[MAXN];
struct node {
int to,next;
}E[MAXN * 2];
int head[MAXN * 2],sumE;
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
int get_id(int u,char c) {
if(s[u] == 'A') return c == 'B' ? u * 2 : u * 2 + 1;
if(s[u] == 'B') return c == 'A' ? u * 2 : u * 2 + 1;
if(s[u] == 'C') return c == 'A' ? u * 2 : u * 2 + 1;
}
char get_ch(int u) {
if(s[u / 2] == 'A') return (u & 1) ? 'C' : 'B';
if(s[u / 2] == 'B') return (u & 1) ? 'C' : 'A';
if(s[u / 2] == 'C') return (u & 1) ? 'B' : 'A';
}
int sta[MAXN],top,dfn[MAXN],low[MAXN],idx,col[MAXN],tot,instack[MAXN];
vector<int> ver[MAXN];
void tarjan(int u) {
sta[++top] = u;
dfn[u] = low[u] = ++idx;
instack[u] = 1;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(instack[v] == 1) {
low[u] = min(low[u],dfn[v]);
}
else if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u],low[v]);
}
}
if(low[u] == dfn[u]) {
++tot;
while(1) {
int x = sta[top--];
col[x] = tot;
ver[tot].pb(x);
instack[x] = 2;
if(x == u) break;
}
}
}
bool check() {
memset(head,0,sizeof(head));
sumE = 0;
for(int i = 1 ; i <= M ; ++i) {
if(c[0][i][1] == s[u[i]]) continue;
if(c[1][i][1] == s[v[i]]) {
int x = get_id(u[i],c[0][i][1]);
add(x,x ^ 1);
}
else {
int x = get_id(u[i],c[0][i][1]),y = get_id(v[i],c[1][i][1]);
add(x,y);add(y ^ 1,x ^ 1);
}
}
for(int i = 1 ; i <= tot ; ++i) ver[i].clear();
memset(sta,0,sizeof(sta));top = 0;
memset(dfn,0,sizeof(dfn));idx = 0;
memset(low,0,sizeof(low));
memset(col,0,sizeof(col));tot = 0;
memset(instack,0,sizeof(instack));
for(int i = 2 ; i <= N * 2 + 1; ++i) {
if(!dfn[i]) tarjan(i);
}
for(int i = 2 ; i <= N * 2 + 1 ; i += 2) {
if(col[i] == col[i ^ 1]) return false;
}
memset(L,0,sizeof(L));
for(int i = 1 ; i <= tot ; ++i) {
for(auto k : ver[i]) {
if(!L[k / 2]) {
L[k / 2] = get_ch(k);
}
}
}
return true;
}
bool dfs(int dep) {
if(dep > N) {
if(check()) return true;
return false;
}
if(s[dep] != 'x') {return dfs(dep + 1);}
else {
for(int i = 0 ; i <= 2 ; ++i) {
s[dep] = 'A' + i;
if(dfs(dep + 1)) return true;
}
}
return false;
}
void Init() {
scanf("%d%d",&N,&D);
scanf("%s",s + 1);
for(int i = 1 ; i <= N ; ++i) {
if(s[i] != 'x') s[i] = s[i] - 'a' + 'A';
}
scanf("%d",&M);
for(int i = 1 ; i <= M ; ++i) {
scanf("%d%s%d%s",&u[i],c[0][i] + 1,&v[i],c[1][i] + 1);
}
}
void Solve() {
if(!dfs(1)) {puts("-1");return;}
for(int i = 1 ; i <= N ; ++i) {
putchar(L[i]);
}
putchar('\n');
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
上一篇:小甲鱼Python视频课后答案(第一讲)---仅记录学习


下一篇:Python类中super()和__init__()的关系