【NOI2017游戏】 枚举+2SAT
%%%2SAT大神love
小 L 计划进行 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏。
小 L 的赛车有三辆,分别用大写字母 、B、C 表示。地图一共有四种,分别用小写字母、a、b、c 表示。
其中,赛车 不适合在地图 a 上使用,赛车 B 不适合在地图 b 上使用,赛车 C 不适合在地图 c 上使用,而地图 则适合所有赛车参加。
适合所有赛车参加的地图并不多见,最多只会有 张。
场游戏的地图可以用一个小写字母组成的字符串描述。例如:S 表示小L计划进行 8 场游戏,其中第 场和第 场的地图类型是 ,适合所有赛车,第 2场和第 场的地图是 ,不适合赛车 ,第 场和第 场的地图是 ,不适合赛车 ,第 场和第 场的地图是 ,不适合赛车 。
小 L 对游戏有一些特殊的要求,这些要求可以用四元组 (i, h_i, j, h_j) 来描述,表示若在第 i 场使用型号为 h_i 的车子,则第 场游戏要使用型号为 h_j 的车子。
你能帮小 L 选择每场游戏使用的赛车吗?如果有多种方案,输出任意一种方案。
如果无解,输出
小 L 计划进行 3 场游戏,其中第 场的地图类型是 x,适合所有赛车,第 场和第 3 场的地图是,不适合赛车 。
小 L 希望:若第 场游戏使用赛车 A,则第 2 场游戏使用赛车 。
那么为这 场游戏分别安排赛车 A、、A 可以满足所有条件。
若依次为 场游戏安排赛车为 BBB 或 BAA时,也可以满足所有条件,也被视为正确答案。
但依次安排赛车为 AAB 或 ABC 时,因为不能满足所有条件,所以不被视为正确答案。
除了万能图就是一个裸的2-sat依赖.考虑万能图也就是直接2^d枚举图是什么就可以了(只用考虑其中两种情况,因为对于剩下情况的已经考虑过了).
这里学到了一个新操作,一般的想法染色找方案都是建立反图之后top-sort一下.但是如果是对偶图,满足所属强连通分量小的在反图拓扑图上的拓扑序越大(优先涂色).那么就判以下就可以了.
-1。
输入格式
输入第一行包含两个非负整数 ,。
输入第二行为一个字符串 S。
n, d, S 的含义见题目描述,其中 包含 个字符,且其中恰好 d 个为小写字母 x。
输入第三行为一个正整数 ,表示有 m 条用车规则。
接下来 行,每行包含一个四元组 i,h_i,j,h_j ,其中 i,j 为整数,h_i,h_j 为字符 A 、B 或 C,含义见题目描述。
输出格式
输出一行。
若无解输出
-1。
样例
样例输入
3 1
xcc
1
1 A 2 B
样例输出
ABA
数据范围与提示
除了万能图就是一个裸的2-sat依赖.考虑万能图也就是直接2^d枚举图是什么就可以了(只用考虑其中两种情况,因为对于剩下情况的已经考虑过了).
这里学到了一个新操作,一般的想法染色找方案都是建立反图之后top-sort一下.但是如果是对偶图,满足所属强连通分量小的在反图拓扑图上的拓扑序越大(优先涂色).那么就判以下就可以了.
#include<stdio.h>
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 4e5 + 5;
int n,d,m;
char ss[maxn];
struct node{
int i,j; char hi,hj;
}xj[maxn];
int tot;
int st[15],tp;
int en[maxn],nt[maxn],la[maxn],owo;
void adg(int x,int y) {
en[++owo] = y; nt[owo] = la[x]; la[x] = owo;
}
int dfn[maxn] , low[maxn], dfx , blo[maxn],scc;
bool inst[maxn]; int sta[maxn],top;
int dy[maxn][3];
int ANS[maxn];
void tarjan(int x) {
low[x] = dfn[x] = ++dfx;
sta[++top] = x; inst[x] = 1;
for(int it=la[x];it;it=nt[it]) {
int y = en[it];
if(!dfn[y]) {
tarjan(y);
low[x] = min(low[x],low[y]);
} else if(inst[y]) low[x] = min(low[x],dfn[y]);
}
if(low[x]==dfn[x]) {
int y; ++scc;
do{
y = sta[top--];
inst[y] = 0;
blo[y] = scc;
}while(y!=x);
}
}
int XF(int x) {
return x>n?x-n:x+n;
}
bool isok() {
owo = dfx = scc = 0;
for(int i=1;i<=n;i++) {
int zz = 0;
for(int j=0;j<3;j++) {
if(ss[i]-'A'!=j&&(!zz)) dy[i][j] = i,zz=1;
else if(ss[i]-'A'==j) dy[i][j] = -1;
else dy[i][j] = i+n;
}
ANS[i] = 0;
}
for(int i=1;i<=tot;i++) {
la[i] = low[i] = dfn[i] = blo[i] = 0;
}
for(int i=1;i<=m;i++) {
int xx = xj[i].i; char ox = xj[i].hi;
int yy = xj[i].j; char oy = xj[i].hj;
if(ox==ss[xx]) continue;
if(oy==ss[yy]) adg(dy[xx][ox-'A'],XF(dy[xx][ox-'A']));
else {
adg(dy[xx][ox-'A'],dy[yy][oy-'A']);
adg(XF(dy[yy][oy-'A']),XF(dy[xx][ox-'A']));
}
}
for(int i=1;i<=tot;i++) {
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=n;i++) {
if(blo[i]==blo[i+n]) return 0;
if(blo[i]<blo[i+n]) ANS[i] = 1; else ANS[i] = 2;
}
for(int i=1;i<=n;i++) {
for(int j=0;j<3;j++) {
if(dy[i][j]==-1) continue;
if(--ANS[i]==0) {
putchar(j+'A');
}
}
}
return 1;
}
void dfs(int now) {
if(now==d+1) {
if(isok()) exit(0);
return;
}
ss[st[now]] = 'A';
dfs(now+1);
ss[st[now]] = 'B';
dfs(now+1);
}
int main() {
scanf("%d%d",&n,&d); d = 0;
tot = 2*n;
scanf("%s",&ss[1]);
for(int i=1;i<=n;i++) {
if(ss[i]=='x') st[++d] = i;
else ss[i] = ss[i]-'a'+'A';
}
scanf("%d",&m);
for(int i=1;i<=m;i++) {
scanf("%d %c%d %c",&xj[i].i,&xj[i].hi,&xj[i].j,&xj[i].hj);
}
dfs(1);
puts("-1");
}

浙公网安备 33010602011771号