LOJ_2305_「NOI2017」游戏 _2-sat
LOJ_2305_「NOI2017」游戏 _2-sat
题意:
给你一个长度为n的字符串S,其中第i个字符为a表示第i个地图只能用B,C两种赛车,为b表示第i个地图只能用A,C两种赛车,为c表示第i个地图只能用A,B两种赛车。
另有d(d<=8)个字符x,表示这个地图三种车都能用。有m个要求,(i,hi,j,hj)表示如果在第i场用了hi,在第j场必须用hj。
求一种满足要求的方案,若无解输出-1。
样例输入
3 1
xcc
1
1 A 2 B
样例输出
ABA
分析:先思考如果没有万能的x该怎么做。每个地图只有两种选择,不妨把这两种选择看作0和1,然后按要求建图。
1.如果hi不在i可选的范围内,显然不需要做任何事。
2.如果hj不在j可选的范围内,显然不能选hi这个,那么我们连i(hi)->i(hi^1)表示i位置不能选hi。
3.如果i==j,当hi!=hj时仿照2那么连边,否则什么也不做
其他的情况:连i(hi)->j(hj) 和 j(hj^1)->i(hi^1)
然后tarjan缩点,如果i(0)和i(1)在一个强连通分量中,则不合法,否则输出方案。
输出方案时对于点i的两种选择,要选择拓扑序靠前的那个,但其实缩点后的强连通分量的编号是满足拓扑序的(这个真的厉害),直接输出即可。
然后考虑有x怎么做,首先一个想法是3^d枚举x是什么,然后验证。但其实是不必要的,因为x相当于三个都可能选,如果x这里既不能是a,也不能是b,那么枚举c就是没有意义的。
因为我们枚举a和b就已经包含了所有情况。所以只需2^d枚举即可。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define N 100050
char s[N],op1[10],op2[10];
int n,d,m;
int head[N],to[N<<1],nxt[N<<1],cnt,low[N],dfn[N],tot,scc,fs[N],sd[N];
int xx[N],yy[N],zz[N],ww[N],pos[10],ins[N],S[N],bl[N];
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void tarjan(int x) {
dfn[x]=low[x]=++tot;
int i;
S[++S[0]]=x;
ins[x]=1;
for(i=head[x];i;i=nxt[i]) {
if(!dfn[to[i]]) {
tarjan(to[i]);
low[x]=min(low[x],low[to[i]]);
}else if(ins[to[i]]) {
low[x]=min(low[x],dfn[to[i]]);
}
}
if(low[x]==dfn[x]) {
int t=S[S[0]--]; bl[t]=++scc; ins[t]=0;
while(x!=t) {
t=S[S[0]--]; bl[t]=scc; ins[t]=0;
}
}
}
void init() {
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
cnt=0; tot=0; scc=0; S[0]=0;
}
bool check() {
int i;
init();
for(i=1;i<=m;i++) {
int u=xx[i],v=zz[i],g=yy[i],h=ww[i];
if(g!=fs[u]&&g!=sd[u]) continue;
if(u==v) {
if(g!=h) {
if(g==fs[u]) add(u,u+n);
else add(u+n,u);
}
continue;
}
if(h==fs[v]||h==sd[v]) {
if(g==fs[u]) {
if(h==fs[v]) {
add(u,v);
add(v+n,u+n);
}else {
add(u,v+n);
add(v,u+n);
}
}else {
if(h==fs[v]) {
add(u+n,v);
add(v+n,u);
}else {
add(u+n,v+n);
add(v,u);
}
}
}else {
if(g==fs[u]) add(u,u+n);
else add(u+n,u);
}
}
for(i=1;i<=n+n;i++) if(!dfn[i]) tarjan(i);
for(i=1;i<=n;i++) if(bl[i]==bl[i+n]) return 0;
return 1;
}
void print() {
int i;
for(i=1;i<=n;i++) {
if(bl[i]<bl[i+n]) {
printf("%c",fs[i]+'A'-1);
}else {
printf("%c",sd[i]+'A'-1);
}
}
}
int main() {
//puts("CA"); return 0;
//freopen("tt.in","r",stdin);
//freopen("tt.out","w",stdout);
scanf("%d%d%s%d",&n,&d,s+1,&m);
int mask=(1<<d)-1;
int i,j;
for(i=1;i<=n;i++) {
if(s[i]=='x') pos[++pos[0]]=i;
if(s[i]=='a') {
fs[i]=2; sd[i]=3;
}else if(s[i]=='b') {
fs[i]=1; sd[i]=3;
}else if(s[i]=='c') {
fs[i]=1; sd[i]=2;
}
}
for(i=1;i<=m;i++) {
scanf("%d%s%d%s",&xx[i],op1,&zz[i],op2);
yy[i]=op1[0]-'A'+1; ww[i]=op2[0]-'A'+1;
}
for(i=0;i<=mask;i++) {
for(j=1;j<=d;j++) {
if(i&(1<<(j-1))) {
fs[pos[j]]=2; sd[pos[j]]=3;
}else {
fs[pos[j]]=1; sd[pos[j]]=3;
}
}
if(check()) {
print();
puts("");
return 0;
}
}
puts("-1");
return 0;
}
LOJ_2305_「NOI2017」游戏 _2-sat的更多相关文章
- 「NOI2017」游戏
「NOI2017」游戏 题目描述 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 \(A\).\(B\).\ ...
- loj #2305. 「NOI2017」游戏
#2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...
- LOJ2305 「NOI2017」游戏
「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...
- 「NOI2017」游戏 解题报告
「NOI2017」游戏 \(d\)这么小,你考虑直接对\(d\)个东西暴力 枚举\(x\)为\(a\)或\(b\)(\(c\)就不用了,因为\(a,b\)已经包含\(c\))了,剩下的就是个\(2-s ...
- loj#2305. 「NOI2017」游戏 2-sat
链接 https://loj.ac/problem/2305 https://www.luogu.org/problemnew/show/P3825 思路 3-sat神马的就不要想了,NP问题 除去x ...
- 【LOJ】 #2305. 「NOI2017」游戏
题解 枚举x所在的地图的颜色,然后2-SAT建边 如果v所在的地图刚好是不能选的,那么u这边只能选另一种颜色 否则就是u的颜色到v的颜色 v的另一种颜色到u的另一种颜色 代码 #include < ...
- LG3825/BZOJ4945/LOJ2305 「NOI2017」游戏 dfs+2-SAT
问题描述 LG3825 BZOJ4945 LOJ2305 题解 发现对于每个地图,如果没有\(A,B,C\)地图不可以使用\(a,b,c\),就是一个\(\mathrm{3-SAT}\)问题. 有了这 ...
- 「HNOI2018」游戏
「HNOI2018」游戏 解题思路 首先没有锁上的门可以缩点缩掉,然后对于一扇锁上的门,如果钥匙在左边,那么右边就永远不可能到达左边,同理如果钥匙在右边,左边就永远不可能到达右边. 然后考虑一个暴力的 ...
- LOJ2303 「NOI2017」蚯蚓排队
「NOI2017」蚯蚓排队 题目描述 蚯蚓幼儿园有$n$只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从$1$到$n$的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示 ...
随机推荐
- java并发包分析之———Atomic类型
一.何谓Atomic? Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位.计算机中的Atomic是指不能分割成若干部分的意思.如果一段代码被认为是Atomic,则表示这段代码在执行过 ...
- MySQL/MariaDB中的事务和事务隔离级别
本文目录:1.事务特性2.事务分类 2.1 扁平事务 2.2 带保存点的扁平事务 2.3 链式事务 2.4 嵌套事务 2.5 分布式事务3.事务控制语句4.显式事务的次数统计5.一致性非锁定读(快照查 ...
- Day4_迭代器
迭代器: 是一个重复的过程,每一次重复都是基于上一次的结果而来. 可迭代对象: 凡是对象有_iter_方法(对象._iter_),该对象就是可迭代对象. 字符串,列表,元组,字典等都是可迭代对象. 可 ...
- 零基础自学Python十天,写了一款猜数字小游戏,附源码和软件下载链接!
自学一门语言最重要的是要及时给自己反馈,那么经常写一些小程序培养语感很重要,写完可以总结一下程序中运用到了哪些零散的知识点. 本程序中运用到的知识点有: 1.输入输出函数 (input.print) ...
- 【.NET Core】ASP.NET Core之IdentityServer4(1):快速入门
[.NET Core]ASP.NET Core之IdentityServer4 本文中的IdentityServer4基于上节的jenkins 进行docker自动化部署. 使用了MariaDB,EF ...
- Coursera-AndrewNg(吴恩达)机器学习笔记——第三周
一.逻辑回归问题(分类问题) 生活中存在着许多分类问题,如判断邮件是否为垃圾邮件:判断肿瘤是恶性还是良性等.机器学习中逻辑回归便是解决分类问题的一种方法.二分类:通常表示为yϵ{0,1},0:&quo ...
- 从GitHub中整理出来的15个最受欢迎的Python开源框架,你喜欢哪个
从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python Web应用开发框架 Djang ...
- webpack的css压缩不兼容IOS8问题探索
webpack使用postcss的autoprefixer插件,并在压缩css时使用了cssnano,处理不当的情况下会导致压缩css后,部分兼容前缀(比如-webkit-)被删除的问题. postc ...
- CSS学习笔记二:css 画立体图形
继上一次学了如何去运用css画平面图形,这一次学如何去画正方体,从2D向着3D学习,虽然有点满,但总是一个过程,一点一点积累,然后记录起来. Transfrom3D 在这一次中运用到了一下几种属性: ...
- 如何书写一篇能看懂的html和CSS代码
在书写html和CSS过程中,如果只是想要实现网页的外观和基本功能,那么简单的书写代码就可以满足需求,甚至不需要使用类名或者注释等.但实际上,这么写肯定是不行的,首先对于类同结构的重复书写就是一件很浪 ...