对于所有的x,我们枚举他的地图类型,事实上我们只需要枚举前两种地形就可以覆盖所有的情况。

之后就变成了裸的2-sat问题。

对于一个限制,我们分类讨论:

1.h[u]不可选,跳过

2.h[v]不可选,则h[v]也不可选,将u与u‘连边,表示u不可选。

3.否则从u向v连边表示选u就必须选v,从u’向v‘连边表示选v'就必须选u’(逆否命题)。

tarjan缩点判断可行性。

输出方案按照缩点编号选择编号小的点输出即可(逆序拓扑序)。

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 400005
using namespace std;
inline int read() {
int x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
struct Edge {int to,nxt;}e[maxn*];
int head[maxn],cnt;
void add(int u,int v) {e[cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt++;}
struct Ask {int u,v;char a[],b[];}q[maxn];
int n,d,pos[maxn],m;
char s[maxn],cs[maxn];
bool flag=;
int dfn[maxn],low[maxn],tot,bel[maxn],par[maxn],l[maxn],r[maxn],sta[maxn],top,scc;
bool vis[maxn],inq[maxn];
void init() {
memset(head,-,sizeof(head));cnt=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(bel,,sizeof(bel));tot=;scc=;
memset(vis,,sizeof(vis));
memset(inq,,sizeof(inq));
}
void tarjan(int x) {
dfn[x]=low[x]=++tot;sta[++top]=x;inq[x]=;
for(int i=head[x];i>=;i=e[i].nxt) {
int to=e[i].to;
if(!dfn[to]) {
tarjan(to);
low[x]=min(low[x],low[to]);
}
else if(inq[to]) {low[x]=min(low[x],dfn[to]);}
}
if(dfn[x]==low[x]) {
scc++;
while() {
inq[sta[top]]=;
bel[sta[top--]]=scc;
if(sta[top+]==x) break;
}
}
}
int que[maxn],fro,tail,in[maxn];
void work() {
init();
for(int i=;i<=n;i++) {
int ttmp=;
if(s[i]=='x') {s[i]=cs[i];ttmp=;}
if(s[i]=='a') {l[i]=i+n,r[i]=i+n+n;}
if(s[i]=='b') {l[i]=i,r[i]=i+n+n;}
if(s[i]=='c') {l[i]=i,r[i]=i+n;}
if(ttmp==) s[i]='x';
par[l[i]]=r[i];par[r[i]]=l[i];vis[r[i]]=vis[l[i]]=;
}
int ql,qr;
for(int i=;i<=m;i++) {
if(q[i].a[]=='A') ql=q[i].u;
else if(q[i].a[]=='B') ql=q[i].u+n;
else ql=q[i].u+n+n;
if(q[i].b[]=='A') qr=q[i].v;
else if(q[i].b[]=='B') qr=q[i].v+n;
else qr=q[i].v+n+n;
if(ql==qr) continue;
if(!vis[ql]) continue;
if(!vis[qr]) {
add(ql,par[ql]);
continue;
}
add(ql,qr);add(par[qr],par[ql]);
}
for(int i=;i<=n+n+n;i++) {if(vis[i]&&!dfn[i]) tarjan(i);}
for(int i=;i<=n+n+n;i++) {
if(!vis[i]) continue;
if(bel[i]==bel[par[i]]) return;
}
flag=;
for(int i=;i<=n;i++) {
int out=;
if(bel[l[i]]<bel[r[i]]) out=l[i];
else out=r[i];
if(out==i) printf("A");
else if(out==i+n) printf("B");
else printf("C");
}
}
void dfs(int x) {
if(x==d+) {
work();
if(flag) exit();
return;
}
cs[pos[x]]='a';dfs(x+);
cs[pos[x]]='b';dfs(x+);
}
int main() {
n=read(),d=read();
scanf("%s",s+);
for(int i=;i<=n;i++) {if(s[i]=='x') pos[++pos[]]=i;}
m=read();
for(int i=;i<=m;i++) {q[i].u=read();scanf("%s",q[i].a+);q[i].v=read();scanf("%s",q[i].b+);}
dfs();printf("-1\n");
}

[BZOJ4945][Noi2017]游戏 2-sat的更多相关文章

  1. [bzoj4945][Noi2017]游戏

    题目大意:有$n$个位置,有三种数,每个位置只可以填一种数,$d(d\leqslant8)$个位置有三种选择,其他位置只有两种选择.有一些限制,表示第$i$个位置选了某种数,那么第$j$个位置就只能选 ...

  2. 【BZOJ4945】[Noi2017]游戏 2-SAT

    [BZOJ4945][Noi2017]游戏 题目描述 题解:2-SAT学艺不精啊! 这题一打眼看上去是个3-SAT?哎?3-SAT不是NPC吗?哎?这题x怎么只有8个?暴力走起! 因为x要么不是A要么 ...

  3. P3825 [NOI2017]游戏

    题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...

  4. [Luogu P3825] [NOI2017] 游戏 (2-SAT)

    [Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...

  5. BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...

  6. 【bzoj4945】[Noi2017]游戏(搜索+2-sat)

    bzoj 洛谷 题意: 现在有\(a,b,c\)三种车,每个赛道可能会存在限制:\(a\)表示不能选择\(a\)类型的赛车,\(b,c\)同理:\(x\)表示该赛道不受限制,但\(x\)类型的个数$\ ...

  7. 并不对劲的bzoj4945:loj2305:uoj317:p3825[NOI2017]游戏

    题目大意 2-SAT,其中有\(d\)(\(d\leq 8\))个点是\(3-SAT\). 题解 枚举\(d\)个点不取三个中(假设三个为\(a,b,c\))的哪一个,然后整体变成做\(2-SAT\) ...

  8. bzoj3825 NOI2017 游戏

    题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用一张地 ...

  9. [NOI2017]游戏(2-SAT)

    这是约半年前写的题解了,就搬过来吧 感觉这是NOI2017最水的一题(当然我还是不会2333),因为是一道裸的2-SAT.我就是看着这道题学的2-SAT 算法一:暴力枚举.对于abc二进制枚举,对于x ...

随机推荐

  1. (二)SMO算法

    11 SMO优化算法(Sequential minimal optimization) SMO算法由Microsoft Research的John C. Platt在1998年提出,并成为最快的二次规 ...

  2. HDU 6199 DP

    gems gems gems Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. C++ ------ 互斥锁、原子操作的性能测试

    atomic原子操作:是在新标准C++11,引入了原子操作的概念,并通过这个新的头文件提供了多种原子操作数据类型,例如,atomic_bool,atomic_int等等 测试程序 #include & ...

  4. 怎么查看ubuntu是32bit还是64bit的?

    怎么查看ubuntu是32bit还是64bit的?你用uname -a的时候看到的i686就是32bit的----

  5. 居中div,居中浮动的元素

    定位法:position:absolute 如果子级div有定义宽和高的话就可以用这个方法.注意:margin-top,和margin-left的值均为高和宽值的一半 margin:auto法 这个也 ...

  6. OpenCV---色彩空间(二)HSV追踪颜色对象和通道分离与合并

    一:HSV追踪有颜色对象 def inRange(src, lowerb, upperb, dst=None) #lowerb是上面每个颜色分段的最小值,upperb是上面每个颜色分段的最大值,都是列 ...

  7. HDU 2685 GCD推导

    求$(a^n-1,a^m-1) \mod k$,自己手推,或者直接引用结论$(a^n-1,a^m-1) \equiv a^{(n,m)}-1 \mod k$ /** @Date : 2017-09-2 ...

  8. How To Build Compelling Stories From Your Data Sets

    How To Build Compelling Stories From Your Data Sets Every number has a story. As a data scientist, y ...

  9. 《JavaScript 实战》:实现图片幻滑动展示效果

    滑动展示效果主要用在图片或信息的滑动展示,也可以设置一下做成简单的口风琴(Accordion)效果.这个其实就是以前写的图片滑动展示效果的改进版,那是我第一篇比较受关注的文章,是时候整理一下了. 有如 ...

  10. c语言中使用自带的qsort(结构体排序)+ 快排

    c中没有自带的sort函数emm 不过有自带的qsort函数 (其实用法都差不多(只是我经常以为c中有sort 头文件要用 #include <stdlib.h> 一定要重新把指针指向的值 ...