【NOI2017】游戏(搜索,2-sat)

题面

BZOJ的SPJ是假的

兹磁洛谷

题解

如果没有\(x\)地图的影响

这就是一个裸的\(2-sat\)问题

但是现在有不超过\(8\)个\(x\)地图的影响

我们不难想到枚举\(x\)地图的状态再来\(2-sat\)判断剩余是否可行。

这样的复杂度是\(O(3^dn)\),稍微算一下发现这个复杂度有点假

考虑如何优化,我们枚举\(x\)地图不连什么

表面上看起来还是\(O(3^dn)\)

但是,当他等价于\(a,b\)两种地图时,\(2^d\)种方案中一定会包含着最后的解,也就是说,\(a,b\)两种地图替换\(x\)的所有状态,等价于\(a,b,c\)三种地图替换\(x\)

这样的复杂度是\(O(2^dn)\)

现在考虑\(2-sat\)如何连边

对于限制\(i->j\)

显然直接连接\(i->j\)

并且,如果\(j'\)被选择,那么必须选择\(i'\)

所以,同时连接\(j'->i'\)

一些没有意义的连边可以直接省略。

至于输出方案,\(Tarjan\)求出来的强连通分量已经和拓扑序相关,因此没有必要重新建图拓扑排序

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 333333
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
char g[MAX];
struct Limit{int i,j;char a,b;}q[MAX];
int n,D,m,pos[20];
struct Line{int v,next;}e[MAX<<3];
int h[MAX],cnt;
int p[MAX];
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
bool fl;
void Build()
{
memset(h,0,sizeof(h));cnt=1;fl=true;
for(int i=1;i<=n;++i)
{
p[i]=p[i+n]=p[i+n+n]=0;
if(g[i]=='a')p[i+n]=i+n+n,p[i+n+n]=i+n;
else if(g[i]=='b')p[i]=i+n+n,p[i+n+n]=i;
else p[i]=i+n,p[i+n]=i;
}
for(int i=1;i<=m;++i)
{
int u=q[i].i,v=q[i].j;
int a=q[i].a-65,b=q[i].b-65;
if(u==v&&a==b)continue;
if(g[u]-97==a)continue;
if(g[v]-97==b){Add(u+a*n,p[u+a*n]);continue;}
Add(u+a*n,v+b*n);
Add(p[v+b*n],p[u+a*n]);
}
}
int dfn[MAX],low[MAX],S[MAX],top;
int gr,G[MAX],tim,ans[MAX];
bool Ins[MAX];
void Tarjan(int u)
{
dfn[u]=low[u]=++tim;
S[++top]=u;Ins[u]=true;
int v;
for(int i=h[u];i;i=e[i].next)
{
v=e[i].v;
if(!dfn[v])Tarjan(v),low[u]=min(low[u],low[v]);
else if(Ins[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
++gr;
do{v=S[top--];G[v]=gr;Ins[v]=false;}while(u!=v);
}
}
void Calc()
{
Build();gr=tim=0;if(!fl)return;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(G,0,sizeof(G));
for(int i=1;i<=n+n+n;++i)if(!dfn[i])Tarjan(i);
for(int i=1;i<=n+n+n;++i)if(G[i]==G[p[i]])return;
for(int i=1;i<=n;++i)
{
if(g[i]=='a')(G[i+n]<G[i+n+n])?ans[i]=1:ans[i]=2;
if(g[i]=='b')(G[i]<G[i+n+n])?ans[i]=0:ans[i]=2;
if(g[i]=='c')(G[i]<G[i+n])?ans[i]=0:ans[i]=1;
}
for(int i=1;i<=n;++i)putchar(ans[i]+65);puts("");
exit(0);
}
void dfs(int x)
{
if(x==D+1){Calc();return;}
g[pos[x]]='a';dfs(x+1);
g[pos[x]]='b';dfs(x+1);
}
int main()
{
n=read();D=read();D=0;
scanf("%s",g+1);
m=read();
for(int i=1;i<=m;++i)
q[i].i=read(),q[i].a=getchar(),q[i].j=read(),q[i].b=getchar();
for(int i=1;i<=n;++i)
if(g[i]=='x')pos[++D]=i;
dfs(1);
puts("-1");
return 0;
}

【BZOJ4945】【NOI2017】游戏(搜索,2-sat)的更多相关文章

  1. BZOJ 4945 NOI2017 游戏 搜索+2-SAT

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4945 分析: 首先考虑没有x的情况,发现有一个明显的推理模型,容易看出来可以用2-SAT ...

  2. [BZOJ4945][Noi2017]游戏 2-sat

    对于所有的x,我们枚举他的地图类型,事实上我们只需要枚举前两种地形就可以覆盖所有的情况. 之后就变成了裸的2-sat问题. 对于一个限制,我们分类讨论: 1.h[u]不可选,跳过 2.h[v]不可选, ...

  3. [bzoj4945][Noi2017]游戏

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

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

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

  5. P3825 [NOI2017]游戏

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

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

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

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

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

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

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

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

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

  10. NOIp 2011 mayan游戏 搜索

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

随机推荐

  1. 查看Linux系统版本的命令

    1.lsb_release -a,即可列出所有版本信息: [root@S-CentOS ~]# lsb_release -a LSB Version: :base-4.0-amd64:base-4.0 ...

  2. P,V操作及同步互斥实例

    无论是计算机考研.计算机软件水平考试.计算机操作系统期末考试还是其他计算机岗位考试,P.V原语操作都是一个常考点.下面笔者总结了关于P.V操作的一些知识. 信号量是最早出现的用来解决进程同步与互斥问题 ...

  3. 列出连通集(mooc)

    给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点. 输入格式: 输入第1 ...

  4. JAVA学习笔记--正则表达式

    正则表达式是一种强大而灵活的文本处理工具.使用正则表达式,可以让我们以编程的方式构造复杂的文本,并对输入的字符串进行搜索. 一.基础正则表达式语法(表格来自J2SE6_API) 字符 x 字符 x \ ...

  5. day09,10 函数

    一.函数 什么是函数 函数: 对代码块和功能的封装和定义 定义一个事情或者功能. 等到需要的时候直接去用就好了. 那么这里定义的东西就是一个函数. 语法: def 函数名(形参): 函数体 函数名(实 ...

  6. 【RL系列】蒙特卡罗方法——Soap Bubble

    “肥皂泡”问题来源于Reinforcement Learning: An Introduction(2017). Exercise 5.2,大致的描述如下: 用一个铁丝首尾相连组成闭合曲线,浸入肥皂泡 ...

  7. ThinkPHP - 6 - 学习笔记(2015.5.4)

    解决:OneThink 站点无法被友言uyan后台识别 打开友言uyan插件功能,但OneThink站点无法被友言uyan后台检测到.页面生成的uyan代码为: <!-- UY BEGIN -- ...

  8. 2.hive里的增删改查

    1.hive的增删改查 查询数据库 hive> show databases; OK default Time taken: 0.254 seconds, Fetched: 1 row(s) h ...

  9. 微信小程序-----自定义验证码实现

    这一段时间做小程序项目,使用的是mpvue的框架,需要自己实现验证码输入,模拟input的光标,上一个框输入后后一个框自动获取焦点,删除时从后往前依次删除.下图是整体效果: <template& ...

  10. 第二章 script元素

    <script>元素  async:可选.表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效.  charset:可选.表示通过 ...