【bzoj4945】[Noi2017]游戏(搜索+2-sat)
题意:
现在有\(a,b,c\)三种车,每个赛道可能会存在限制:\(a\)表示不能选择\(a\)类型的赛车,\(b,c\)同理;\(x\)表示该赛道不受限制,但\(x\)类型的个数$$d\leq 8\(。
同时赛道之间还存在\)m\(条关系,每个关系用\)(i\ h_i\ j\ h_j)\(表示,意味着若在第\)i\(个赛道选择\)h_i\(类的车,则必须在\)j\(赛道选择\)h_j\(类的车。
现在问是否存在一种合法安排赛车的方案,有则任意输出一种方案,没有则输出\)-1$。
思路:
- \(x\)类赛道个数较少,我们先不考虑其存在,那么问题变为了一个存在一些限制条件的\(2-sat\)问题,我们先来解决这个问题。
- 对于合法的限制,直接连边即可;若\(i\)赛道不能有\(h_i\),因为我们本来就不考虑\(h_i\)的存在(2-sat问题),那么我们直接无视当前的限制;若\(j\)赛道不能有\(h_j\),此时表示不能选\(h_i\),那么连边\(h_i\rightarrow h_i'\)即可。
- 然后考虑\(x\)类赛道,因为个数很少,所以我们可以直接\(3^d\)枚举选择哪些情况,复杂度变为\(O(3^dn)\)。
- 然后这里有个特别巧妙的想法,就是正难则反,我们考虑枚举不选哪个,那么\(x\)类赛道也变成了某类具体的赛道。首先问题处理上方便了许多,统一为\(2-sat\)问题;其次,复杂度将为\(2^d\),因为假设我们当前不选\(a\),那么可以选择\(b,c\),不选\(b\),那么可以选择\(a,c\),这样可以覆盖所有的情况了。
所以通过\(2^d\)枚举,问题转换为了一个带限制\(2-sat\)问题。感觉还是挺巧妙的,上午有点累没好好想,可惜了QAQ
代码如下:
/*
* Author: heyuhhh
* Created Time: 2019/12/2 11:21:16
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5, M = 1e5 + 5;
int n, m, d;
char s[N], t[N];
int pos[N], tot;
char x[N];
struct Edge {
int i, j;
char pi, pj;
}e[M];
vector<int> G[N], rG[N], vs;
int used[N], bel[N];
void adde(int from, int to) {
G[from].push_back(to);
rG[to].push_back(from);
}
void dfs(int v) {
used[v] = true;
for(int u: G[v]) {
if(!used[u])
dfs(u);
}
vs.push_back(v);
}
void rdfs(int v, int k) {
used[v] = true;
bel[v] = k;
for(int u: rG[v])
if(!used[u])
rdfs(u, k);
}
int scc() {
memset(used, 0, sizeof(used));
vs.clear();
for(int v = 1; v <= 2 * n; ++v)
if(!used[v]) dfs(v);
memset(used, 0, sizeof(used));
int k = 0;
for(int i = (int) vs.size() - 1; i >= 0; --i)
if(!used[vs[i]]) rdfs(vs[i], k++);
return k;
}
void work() {
for(int i = 1; i <= 2 * n; i++) G[i].clear(), rG[i].clear();
for(int i = 1; i <= n; i++) {
if(t[i] == 'a') {
x[i] = 'b';
x[i + n] = 'c';
} else if(t[i] == 'b') {
x[i] = 'a';
x[i + n] = 'c';
} else {
x[i] = 'a';
x[i + n] = 'b';
}
}
for(int i = 1; i <= m; i++) {
int u = e[i].i, v = e[i].j;
char pi = e[i].pi, pj = e[i].pj;
if(t[u] == pi) continue;
if(t[v] == pj) {
if(x[u] == pi) adde(u, u + n);
else adde(u + n, u);
} else {
if(x[u] == pi) {
if(x[v] == pj) adde(u, v), adde(v + n, u + n);
else adde(u, v + n), adde(v, u + n);
} else {
if(x[v] == pj) adde(u + n, v), adde(v + n, u);
else adde(u + n, v + n), adde(v, u);
}
}
}
scc();
for(int i = 1; i <= n; i++) {
if(bel[i] == bel[i + n]) return;
}
for(int i = 1; i <= n; i++) {
if(bel[i] > bel[i + n]) {
printf("%c", x[i] - 'a' + 'A');
} else printf("%c", x[i + n] - 'a' + 'A');
}
cout << '\n';
exit(0);
}
void go(int cur) {
if(cur > tot) {
work(); return;
}
t[pos[cur]] = 'a'; go(cur + 1);
t[pos[cur]] = 'b'; go(cur + 1);
}
void run(){
scanf("%s", s + 1);
for(int i = 1; i <= n; i++) {
t[i] = s[i];
if(s[i] == 'x') pos[++tot] = i;
}
cin >> m;
for(int i = 1; i <= m; i++) {
int u, v;
char pi, pj;
scanf("%d %c %d %c", &u, &pi, &v, &pj);
pi = pi - 'A' + 'a';
pj = pj - 'A' + 'a';
e[i] = Edge {u, v, pi, pj};
}
go(1);
cout << -1 << '\n';
}
int main() {
while(cin >> n >> d) run();
return 0;
}
【bzoj4945】[Noi2017]游戏(搜索+2-sat)的更多相关文章
- BZOJ 4945 NOI2017 游戏 搜索+2-SAT
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4945 分析: 首先考虑没有x的情况,发现有一个明显的推理模型,容易看出来可以用2-SAT ...
- [BZOJ4945][Noi2017]游戏 2-sat
对于所有的x,我们枚举他的地图类型,事实上我们只需要枚举前两种地形就可以覆盖所有的情况. 之后就变成了裸的2-sat问题. 对于一个限制,我们分类讨论: 1.h[u]不可选,跳过 2.h[v]不可选, ...
- [bzoj4945][Noi2017]游戏
题目大意:有$n$个位置,有三种数,每个位置只可以填一种数,$d(d\leqslant8)$个位置有三种选择,其他位置只有两种选择.有一些限制,表示第$i$个位置选了某种数,那么第$j$个位置就只能选 ...
- 【BZOJ4945】[Noi2017]游戏 2-SAT
[BZOJ4945][Noi2017]游戏 题目描述 题解:2-SAT学艺不精啊! 这题一打眼看上去是个3-SAT?哎?3-SAT不是NPC吗?哎?这题x怎么只有8个?暴力走起! 因为x要么不是A要么 ...
- P3825 [NOI2017]游戏
题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...
- [Luogu P3825] [NOI2017] 游戏 (2-SAT)
[Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...
- 并不对劲的bzoj4945:loj2305:uoj317:p3825[NOI2017]游戏
题目大意 2-SAT,其中有\(d\)(\(d\leq 8\))个点是\(3-SAT\). 题解 枚举\(d\)个点不取三个中(假设三个为\(a,b,c\))的哪一个,然后整体变成做\(2-SAT\) ...
- BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...
- NOIp 2011 mayan游戏 搜索
题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...
随机推荐
- amazon爬取流程与思路
第一步:访问分类页面 https://www.amazon.in//gp/site-directory?ref=nav_em_ajax_fail #抓包获得 第二步:获取分类页面下各个分类的url 如 ...
- C lang:character input and output (I/O)
Xx_Introduction Character input and output is by more line character conpose of the text flow Defin ...
- Windows相关操作(备忘)
查看服务端口是否能通:telnet 192.168.1.11 8888 查看端口是否被占用 netstat -ano
- vmstat/top/iostat/route/sar 常用命令
[vmstat]Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控.是对系统的整体情况进行统计,不足之处是无法对某个进程进行深 ...
- Spring Boot修改JSP不用重启的办法
在application.properties文件中添加一行代码解决. Spring Boot 2.0以上添加如下一行: server.servlet.jsp.init-parameters.deve ...
- 服务治理-Resilience4j(限流)
Bulkhead Bulkhead一般用于服务调用客户端,用于限定对特定的服务的并发请求数量,起到一下作用:1.防⽌下游依赖被并发请求冲击2.防⽌发⽣连环故障 1.配置规则“order” //允许最大 ...
- 【数据结构】什么是二叉查找树(BST)
什么是二叉查找树(BST) 1. 什么是BST 对于二叉树中的每个节点X,它的左子树中所有项的值都小于X中的项,它的右子树中所有项的值大于X中的项.这样的二叉树是二叉查找树. 以上是一颗二叉查找树,其 ...
- JavaScript -- 筑基
本片博客记录了我JavaScript筑基阶段的学习内容,JavaScript不是Java,但是我下意识的把它和java对比学习,有些地方比较有趣,有些地方从java角度看,简直匪夷所思,不过现在总体感 ...
- Airtest 之 游戏自动化(5分钟教你王者农药刷金币)
一.准备工作: 1)安装腾讯手游助手,下载王者荣耀,安装启动( 你也可以直接连接手机启动游戏,或者使用其他的模拟器 ) 2)安装AirtestIDE,在设备窗中连接游戏Windows(详情参考笔者另 ...
- PostgreSQL学习之路一
PostgreSQL的扩展PostGIS是最著名的开源GIS数据库. 安装PostgreSQL是第一步. 1.下载PostgreSQL的二进制安装文件 PostgreSQL官网–>Downloa ...