洛谷P3825 [NOI2017]游戏(2-SAT)
果然图论的题永远建图最麻烦……看着题解代码的建图过程真的很珂怕……
先不考虑地图$x$,那么每一个地图都只能用两种赛车,于是我们可以用2-SAT来搞,用$i$表示这个地图能用的第一辆车,$i'$表示它能用的第二辆车
至于怎么连边呢,考虑限制条件$(i,h_i,j,h_j)$,如果$i$不能用$h_i$我们直接忽视这个限制条件,如果$j$不能用$h_j$说明无解,于是我们连边$(i,i')$表示如果选了$i$的第一辆车就无解
否则的话就按一般的2-SAT把上面的限制条件连边即可
然后考虑怎么处理地图$x$,因为$d$最大只有$8$,且可行的方案里每一个地图$x$只要用一辆车,于是我们考虑枚举每一个地图$x$哪一辆车不能用,只需要枚举$A$和$B$即可,如果有解,能用$BC$和能用$AC$的方案里一定有一个可行
于是时间复杂度就是$O((n+m)2^d)$
//minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#define mem(a) (memset(a,0,sizeof(a)))
#define swap(x,y) (x^=y^=x^=y)
#define neg(x) (x>n?x-n:x+n)
using namespace std;
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
inline char getc(){
char ch;while((ch=getchar())!='A'&&ch!='B'&&ch!='C');return ch;
}
const int N=2e5+;
int head[N],Next[N],ver[N],tot;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
int dfn[N],low[N],bl[N],st[N],num,cnt,top,n,m,d;
void tarjan(int u){
dfn[u]=low[u]=++num,st[++top]=u;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(!dfn[v]) tarjan(v),cmin(low[u],low[v]);
else if(!bl[v]) cmin(low[u],dfn[v]);
}
if(dfn[u]==low[u]) for(++cnt;st[top+]!=u;--top) bl[st[top]]=cnt;
}
inline void clear(){
mem(head),mem(dfn),mem(bl),mem(st);
tot=num=cnt=;
}
int a1[N],b1[N],Sooke[N];char s[N],a2[N],b2[N],QAQ[N];
int flag=;
int tran(int x,char ch){
if(s[x]=='a') return ch=='B'?x:x+n;
if(s[x]=='b'||s[x]=='c') return ch=='A'?x:x+n;
if(ch=='C') return x+n;return x;
}
bool solve(){
clear();
for(int i=;i<=m;++i)
if(s[a1[i]]!='x'&&s[b1[i]]!='x'){
if(a2[i]==s[a1[i]]-) continue;
int u=tran(a1[i],a2[i]),v;
if(b2[i]==s[b1[i]]-){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}else{
char o=s[a1[i]],p=s[b1[i]];
int u,v,x=Sooke[a1[i]],y=Sooke[b1[i]];
if(o=='x'&&p=='x'){
if(a2[i]==QAQ[x]) continue;
u=tran(a1[i],a2[i]);
if(b2[i]==QAQ[y]){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}else if(o=='x'&&p!='x'){
if(a2[i]==QAQ[x]) continue;
u=tran(a1[i],a2[i]);
if(b2[i]==s[b1[i]]-){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}else{
if(a2[i]==s[a1[i]]-) continue;
u=tran(a1[i],a2[i]);
if(b2[i]==QAQ[y]){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}
}
for(int i=,l=n<<;i<=l;++i) if(!dfn[i]) tarjan(i);
for(int i=;i<=n;++i) if(bl[i]==bl[i+n]) return ;
for(int i=;i<=n;++i)
if(bl[i]<bl[i+n]){
if(s[i]=='a') putchar('B');
else if(s[i]=='b'||s[i]=='c') putchar('A');
else if(QAQ[Sooke[i]]=='A') putchar('B');
else putchar('A');
}else{
if(s[i]=='a'||s[i]=='b') putchar('C');
else if(s[i]=='c') putchar('B');
else if(QAQ[Sooke[i]]=='A') putchar('C');
else putchar('B');
}
return ;
}
void dfs(int dep){
if(dep>d){
if(!flag) flag=solve();
if(flag) exit();
return;
}
QAQ[dep]='A',dfs(dep+);
QAQ[dep]='B',dfs(dep+);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),read();
scanf("%s",s+),m=read();
for(int i=;i<=n;++i) if(s[i]=='x') Sooke[i]=++d;
for(int i=;i<=m;++i)
a1[i]=read(),a2[i]=getc(),b1[i]=read(),b2[i]=getc();
dfs();
if(!flag) printf("%d",-);
return ;
}
洛谷P3825 [NOI2017]游戏(2-SAT)的更多相关文章
- 洛谷 P3825 [NOI2017]游戏 【2-SAT+状压】
UOJ和洛谷上能A,bzoj 8ms即WA,现在也不是知道为啥--因为我太弱了 先看数据范围发现d非常小,自然想到了状压. 所以先假装都是只能跑两种车的,这显然就是个2-SAT问题了:对于x场没有hx ...
- 洛谷3825 [NOI2017]游戏 2-sat
原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...
- P3825 [NOI2017]游戏
题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...
- 洛谷 P2197 nim游戏
洛谷 P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取 ...
- 洛谷 P1965 转圈游戏
洛谷 P1965 转圈游戏 传送门 思路 每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,--,依此类推,第n − m号位置上的小伙伴走到第 0 号 ...
- [Luogu P3825] [NOI2017] 游戏 (2-SAT)
[Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...
- 洛谷 P1000 超级玛丽游戏
P1000 超级玛丽游戏 题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用. 建议完成本题目后继续尝试P1001.P1008. 题目描述 超级玛丽是一个非常经典的游戏.请你用字符画的形式输出超级 ...
- 【流水调度问题】【邻项交换对比】【Johnson法则】洛谷P1080国王游戏/P1248加工生产调度/P2123皇后游戏/P1541爬山
前提说明,因为我比较菜,关于理论性的证明大部分是搬来其他大佬的,相应地方有注明. 我自己写的部分换颜色来便于区分. 邻项交换对比是求一定条件下的最优排序的思想(个人理解).这部分最近做了一些题,就一起 ...
- $loj10156/$洛谷$2016$ 战略游戏 树形$DP$
洛谷loj Desription Bob 喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的方法.现在他有个问题. 现在他有座古城堡,古城堡的路形成一棵树.他要在这棵树的节点上放置最少数 ...
随机推荐
- react 使用 moment 进行 日期格式化
在react中使用得先导入: import moment from 'moment'; 调用: npm install moment var moment = require('moment'); m ...
- 《Getting Started with WebRTC》第二章 WebRTC技术介绍
<Getting Started with WebRTC>第二章 WebRTC技术介绍 本章作WebRTC的技术介绍,主要讲下面的概念: . 怎样建立P2P的通信 . 有效的信 ...
- JS 计算2个日期相差的天数
<span style="font-size:18px;">function getDays(strDateStart,strDateEnd){ var strSepa ...
- 在OpenStack中绕过或停用security group (iptables)
眼下.OpenStack中默认採用了security group的方式.用系统的iptables来过滤进入vm的流量.这个本意是为了安全,可是往往给调试和开发带来一些困扰. 因此,暂时性的禁用它能够排 ...
- oracle 11G direct path read 非常美也非常伤人
direct path read 在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这种全表扫描就是物理读了. 在10g中,都是通过gc buffer来读 ...
- TinyXML的使用
TinyXML TinyXML是一个简单的小型C ++ XML解析器,可以轻松集成到其他程序中. 它能做什么: 简而言之,TinyXML解析XML文档,并从可以读取,修改和保存的文档对象模型(DOM) ...
- Linux下VLAN功能的实现 (转)
1.Linux网络栈下两层实现 1.1简介 VLAN是网络栈的一个附加功能,且位于下两层.首先来学习Linux中网络栈下两层的实现,再去看如何把VLAN这个功能附加上去.下两层涉及到具体的硬件 ...
- (23) java web的struts2框架的使用-struts动态调用和通配符
一,动态查找 1,配置允许动态调用 <!-- 允许动态方法调用 --> <constant name="struts.enable.DynamicMethodInvocat ...
- throw 、throws 简介
抛出异常抛出异常有三种形式,一是throw,一个throws,还有一种系统自动抛异常.下面它们之间的异同.系统自动抛异常当程序语句出现一些逻辑错误.主义错误或类型转换错误时,系统会自动抛出异常.如: ...
- HDU3652 B-number —— 数位DP
题目链接:https://vjudge.net/problem/HDU-3652 B-number Time Limit: 2000/1000 MS (Java/Others) Memory L ...