题目描述

给出 $n$ 个赛车赛道和A、B、C三种赛车,除了 $d$ 个赛道可以使用所有三种赛车以外每个都只能使用给出的两种之一。另外给出 $m$ 条限制:某个赛道使用X则某另一个赛道必须使用Y。问:是否存在一种方案满足所有条件?输出一种合法方案。

$n\le 50000,d\le 8,m\le 100000$ 。


题解

2-SAT

3-SAT是NP完全问题,由于 $d$ 只有 $8$ ,因此考虑枚举每个万能位置的取值,转化为2-SAT问题。

那么对于一条限制,显然描述对应着一条边;另外一个命题的逆否命题,因此则有:第二个不用Y,第一个就不能用X,还要连这样的边(考场上没有想到对称边,还以为标算不是2-SAT)。

特殊情况:
第一个没有X,则无视这条边;
第二个没有Y,则第一个不能选X,第一个选X向不选X连边。

然后跑tarjan,对立点在同一强连通分量里则不成立,否则有解。缩点建新图跑拓扑排序,对立点中先排到的点不选,后排到的选。

这里有一个小trick:tarjan中强连通分量的编号顺序就是逆拓扑序(考虑tarjan的过程,挺好理解的),因此不用实际拓扑排序,直接比较对立点所属强连通分量编号即可,较小的那个是相应方案。

这样枚举万能位置的选择,每个位置有三种情况。考虑到枚举万能位置不能选什么,一次可以选出两种,只需要枚举两种情况。

时间复杂度 $O(2^dm)$

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
int n , m , flag , px[N] , vx[N] , py[N] , vy[N] , head[N] , to[N << 1] , next[N << 1] , cnt , deep[N] , low[N] , tot , ins[N] , sta[N] , top , bl[N] , num;
char str[N >> 1] , sx[3] , sy[3];
inline void add(int x , int y)
{
to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
inline int getid(int p , int v)
{
if(str[p] == 'a') return v == 0 ? 0 : p * 2 + v - 1;
else if(str[p] == 'b') return v == 1 ? 0 : p * 2 + v / 2;
else return v == 2 ? 0 : p * 2 + v;
}
void tarjan(int x)
{
int i;
deep[x] = low[x] = ++tot , ins[x] = 1 , sta[++top] = x;
for(i = head[x] ; i ; i = next[i])
{
if(!deep[to[i]]) tarjan(to[i]) , low[x] = min(low[x] , low[to[i]]);
else if(ins[to[i]]) low[x] = min(low[x] , deep[to[i]]);
}
if(deep[x] == low[x])
{
int t;
num ++ ;
do
{
t = sta[top -- ];
ins[t] = 0 , bl[t] = num;
}while(t != x);
}
}
void solve()
{
int i , x , y;
memset(head , 0 , sizeof(head));
memset(deep , 0 , sizeof(deep));
cnt = tot = top = num = 0;
for(i = 1 ; i <= m ; i ++ )
{
x = getid(px[i] , vx[i]) , y = getid(py[i] , vy[i]);
if(x)
{
if(y) add(x , y) , add(y ^ 1 , x ^ 1);
else add(x , x ^ 1);
}
}
for(i = 2 ; i <= 2 * n + 1 ; i ++ ) if(!deep[i]) tarjan(i);
for(i = 1 ; i <= n ; i ++ ) if(bl[i << 1] == bl[i << 1 | 1]) return;
flag = 1;
for(i = 1 ; i <= n ; i ++ )
{
if(str[i] == 'a') putchar(bl[i << 1] < bl[i << 1 | 1] ? 'B' : 'C');
else if(str[i] == 'b') putchar(bl[i << 1] < bl[i << 1 | 1] ? 'A' : 'C');
else putchar(bl[i << 1] < bl[i << 1 | 1] ? 'A' : 'B');
}
puts("");
}
void dfs(int x)
{
if(flag) return;
if(x > n)
{
solve();
return;
}
if(str[x] == 'x') str[x] = 'a' , dfs(x + 1) , str[x] = 'b';
dfs(x + 1);
}
int main()
{
int i;
scanf("%d%*d%s%d" , &n , str + 1 , &m);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%s%d%s" , &px[i] , sx , &py[i] , sy) , vx[i] = sx[0] - 'A' , vy[i] = sy[0] - 'A';
dfs(1);
if(!flag) puts("-1");
return 0;
}

【uoj#317】[NOI2017]游戏 2-SAT的更多相关文章

  1. BZOJ 4945 UOJ #317 NOI2017 游戏 2-SAT 拓扑排序

    http://uoj.ac/problem/317 https://www.lydsy.com/JudgeOnline/problem.php?id=4945 我现在的程序uoj的额外数据通过不了,b ...

  2. P3825 [NOI2017]游戏

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

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

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

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

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

  5. bzoj3825 NOI2017 游戏

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

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

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

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

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

  8. Luogu3825 NOI2017 游戏 2-SAT

    传送门 第一眼看上去似乎是一个3-SAT问题 然而\(d \leq 8\)给我们的信息就是:暴力枚举 枚举\(x\)型地图变成\(a\)型地图还是\(b\)型地图(实际上不要枚举\(c\),因为\(a ...

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

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

随机推荐

  1. 2016-2017-2 20155338 实验二《Java面向对象程序设计》实验报告

    2016-2017-2 20155338 实验二<Java面向对象程序设计>实验报告 实验内容: 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握 ...

  2. 微信小程序点击按钮,修改状态

    WXML中: <view wx:if="{{orderstate}} = '待送检' " data-no="{{orderstate}}" bindtap ...

  3. Oracle下如何设置 log_archive_dest

    一:存在 DB_RECOVERY_FILE_DEST 时,如何设置 LOG_ARCHIVE_DEST: SQL> archive log listデータベース・ログ・モード アーカイブ・モード自 ...

  4. dsu on tree总结

    dsu on tree 树上启发式合并.我并不知道为什么要叫做这个名字... 干什么的 可以在\(O(n\log n)\)的时间内完成对子树信息的询问,可横向对比把树按\(dfs\)序转成序列问题的\ ...

  5. [agc006D]Median Pyramid Hard-[二分+乱搞]

    Description 题目大意:给你一个长度为n*2-1的排列,将除了该序列头尾的两个数外的其他数(设为i)变为原序列i-1,i,i+1下标数的中位数.求最后的数是什么.例子如下: Solution ...

  6. cocos2dx2.0 帧动画的创建和播放过程 深入分析

    一.帧动画的创建过程帧动画的实现有四个不可或缺的类,如下:1.CCSpriteFrame:精灵帧信息.存储帧动画的每一帧的纹理基本信息. class CC_DLL CCSpriteFrame : pu ...

  7. 关于scrum敏捷测试

    关于scrum的一些定义 敏捷软件开发方法是一种把新增功能通过较小的循环逐步迭代添加到项目中(的项目管理方法),工作是由自我组织的团队以高效合作的方式拥抱和适应变化来保证客户需求被真正满足的方式来完成 ...

  8. 美国末日AI System设计分享

    引言 好久没有写博客了,这半年在游戏公司工作,过得比较充实,每天不是add feature就是debug,所以忽视了写博客.今天发一篇关于AI博客. 主要是最近看了一些关于"The Last ...

  9. html5shiv 是一个针对 IE 浏览器的 HTML5 JavaScript 补丁,目的是让 IE 识别并支持 HTML5 元素。

    html5shiv 是一个针对 IE 浏览器的 HTML5 JavaScript 补丁,目的是让 IE 识别并支持 HTML5 元素. 各版本html5shiv.js CDN网址:https://ww ...

  10. SICP读书笔记 1.3

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...