【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('
');
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Init();
    Solve();
}
原文地址:https://www.cnblogs.com/ivorysi/p/9051145.html