题目链接

题目大意:有四种场地$a,b,c,x$和三种赛车$A,B,C$,$a$不能跑$A$,$b$不能跑$B$,$c$不能跑$C$,$x$都可以跑。给定$n$个场地和$m$个四元组$(i,h_i,j,h_j)$,意为如果在第$i$个场地跑$h_i$,那么第$j$个场地必须跑$h_j$。输出一种合法方案。若无输出$-1$。

----------------------------------

此题难在建图。把建图搞定就是一个裸的2-SAT板子。

我们规定$0$为每种场地的第一种能跑的车(按字典序),$1$表示第二种能跑的车。对于约束条件,我们有$3$种情况:

1.$h_i$类型的车与$i$冲突,那么我们直接跳过,不用管它。

2.$h_j$类型的车与$j$冲突,那么我们让$i$向$i'$连边,表示如果选择$h_i$则无解。

3.没有冲突情况。那么我们直接按照2-SAT建图方式建就好,即$i$向$j$连边,$j'$向$i'$连边。

对于$x$,我们只要把它当作某一种特定的场地,然后$dfs$枚举所有情况就好。把它当作任意两种场地就可以包含所有可能情况。

时间复杂度$O(2^dn)$。

PS:一开始我超级傻逼,写了一串$if$来判各种情况还各种出锅;后面突然想到只要写个函数判断就行了草。从早上7点来学校写,一直到上午10点才过……

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int dfn[maxn],low[maxn],vis[maxn],pos[maxn],jishu,tot;
stack<int> st;
int head[maxn],cnt,n,m,d;
int query[maxn][];
char ch[maxn][],c[maxn],s[maxn];
struct node
{
int next,to;
}edge[maxn];
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void add(int from,int to)
{
edge[++cnt].next=head[from];
edge[cnt].to=to;
head[from]=cnt;
}
inline void clear()
{
jishu=tot=cnt=;
memset(head,,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(pos,,sizeof(pos));
while(!st.empty()) st.pop();
}
inline void tarjan(int now)
{
dfn[now]=low[now]=++jishu;
st.push(now);vis[now]=;
for (int i=head[now];i;i=edge[i].next)
{
int to=edge[i].to;
if (!dfn[to]) tarjan(to),low[now]=min(low[now],low[to]);
else if (vis[to]) low[now]=min(low[now],dfn[to]);
}
if (low[now]==dfn[now])
{
tot++;
while(st.top()!=now)
{
int x=st.top();st.pop();
vis[x]=;
pos[x]=tot;
}
int x=st.top();st.pop();
vis[x]=;
pos[x]=tot;
}
}
inline bool check(int pos,char x)
{
if (x+==s[pos]) return ;
return ;
}
inline bool get(int pos,char x)
{
if (s[pos]=='a') return x=='B'?:;
else return x=='A'?:;
}
inline void dfs(int now)
{
if (now>n)
{
clear();
for (int i=;i<=m;i++)
{
int a=query[i][],b=query[i][];
if (check(a,ch[i][])) continue;
if (check(b,ch[i][]))
{
int flag=get(a,ch[i][]);
if (!flag) add(a,a+n);
else add(a+n,a);
continue;
}
else
{
int x=get(a,ch[i][]),y=get(b,ch[i][]);
if (x==&&y==) add(a,b),add(b+n,a+n);
if (x==&&y==) add(a,b+n),add(b,a+n);
if (x==&&y==) add(a+n,b),add(b+n,a);
if (x==&&y==) add(a+n,b+n),add(b,a);
}
}
for (int i=;i<=*n;i++) if(!dfn[i]) tarjan(i);
for (int i=;i<=n;i++) if (pos[i]==pos[i+n]) return;
for (int i=;i<=n;i++)
{
if (pos[i]<pos[i+n])
{
if (s[i]=='a') printf("B");
else printf("A");
}
else
{
if (s[i]=='c') printf("B");
else printf("C");
}
}
exit();
}
if (c[now]=='a') s[now]='a',dfs(now+);
if (c[now]=='b') s[now]='b',dfs(now+);
if (c[now]=='c') s[now]='c',dfs(now+);
if (c[now]=='x'){s[now]='a',dfs(now+);s[now]='b',dfs(now+);}
}
int main()
{
n=read(),d=read();
cin>>(c+);
m=read();
for (int i=;i<=m;i++)
{
query[i][]=read(),cin>>ch[i][];
query[i][]=read(),cin>>ch[i][];
}
dfs();
printf("-1");
return ;
}

【NOI2017】游戏 题解(2-SAT+缩点)的更多相关文章

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

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

  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. [UOJ317]【NOI2017】游戏 题解

    题意 ​ 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. ​ 小 L 的赛车有三辆,分别用大写字母 A.B.C 表示.地图一共有四种,分别用小写字 ...

  6. 【题解】NOI2017游戏

    2-SAT.洛谷P3845 一开始以为——怎么有3个呢?后来发现因为每个地图都有一种车是不能用的,所以就等于每一个地图都有两个适应的车啦. 那么对于x类型的地图呢——只有8个,直接2^8暴力枚举每一种 ...

  7. 题解 洛谷 P3825 【[NOI2017]游戏】

    从题面中四元组\((i,h_i,j,h_j)\)限制选择车子型号,不难想到这题要用\(2-SAT\)解决. 考虑转化为\(2-SAT\)模型,发现除地图\(x\)外,其他地图都只有两种车子型号可以参加 ...

  8. bzoj3825 NOI2017 游戏

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

  9. NOI2017 [NOI2017]游戏 【2-sat】

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

随机推荐

  1. ASP.NET基础温习

  2. HttpContext, HttpContextBase, HttpContextWrapper之间关系

    HttpContext是最原始的ASP.NET Context. MVC的目的之一是能够单元测试. HttpContextBase, 是用来在MVC中替代HttpContext.但是这是一个abstr ...

  3. shell进阶篇之字典和数组结合应用案例

    # 现在我们用字典结合数组来实现一个简单的远程管理机 远程管理机的需求:现在需要在一个管理机上实现下列两点内容: 1.需要可以实时查看现有项目运行状态 2.远程登陆任意一台机器 备注:现有的机器如下 ...

  4. 【Python篇】工厂模式

    工厂方法模式 前言 在<设计模式>一书中工厂模式提到了: 工厂方法模式(Factory Method) 抽象工厂模式 (Abstract Factory) 但是在实际过程中还有一种工厂模式 ...

  5. MCU 51-5中断

    中断概念 : 计算机执行某程序时,发生了紧急事件或有特殊请求,CPU暂停某程序的执行, 转而去处理上述事件或请求,处理完毕后再重新执行某程序的过程叫做中断. 数据的输入/输出传送方式: (1)无条件传 ...

  6. 前端03 /css简绍/css选择器

    前端03 /css简绍/css选择器 目录 前端03 /css简绍/css选择器 昨日内容回顾 html标签 常用标签 table标签:表格标签 input标签 select下拉框 textarea多 ...

  7. matlab中的静态变量与全局变量

    matlab中的静态变量和全局变量 1.静态变量 在matlab中,和其他语言一样,函数中的变量一把都是局部变量,也就是说,在函数调用完毕后,变量就会被释放.但是有些时候回希望上次改变的变量在下一次调 ...

  8. centos7.6静默安装oracle 11G RAC

    环境介绍, esxi6.0 ,VMware vSphere Client6.0 linux 版本Centos7.6(最小化安装) Oracle 版本 oracle 11g 11.2.0.4 虚拟化环境 ...

  9. python+requests实现接口自动化

    1. 前言 今年2月调去支持项目接口测试,测试过程中使用过postman.jmeter工具,基本能满足使用,但是部分情况下使用较为麻烦.比如:部分字段存在唯一性校验或字段间有业务性校验,每次请求均需手 ...

  10. DEP(Data Execution Prevention) 数据执行保护

    1.原理 数据执行保护,简称“DEP”,英文全称为“Data Execution Prevention”,是一组在存储器上运行额外检查的硬件和软件技术,有助于防止恶意程序码在系统上运行. 此技术由Mi ...