bzoj

洛谷

题意:

现在有\(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)的更多相关文章

  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:loj2305:uoj317:p3825[NOI2017]游戏

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

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

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

  9. NOIp 2011 mayan游戏 搜索

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

随机推荐

  1. Cross-Site Scripting:Reflected 跨站点脚本:获取

  2. spinand之data buffer

    data buffer简介 spinand一般会有一个内置的data buffer. 以W25N01GV为例,一个page是2048bytes外加64bytes的spare数据,其data buffe ...

  3. Maven pom.xml文件深度学习

    本文介绍Maven项目构建中,pom.xml文件的生成规则和常用节点的使用方法.pom.xml官方网址:http://maven.apache.org/pom.html pom简介 pom作为项目对象 ...

  4. Localize UI Elements 汉化界面(本地化)

    In this lesson, you will learn the basics of localizing visible UI elements. By default, the applica ...

  5. MyBatis初体验

    一.MyBatis 1.简介 曾命名IBatis(老版本), 交给Google维护后,改名为MyBatis(新版本).学习文档: https://mybatis.org/mybatis-3/zh/in ...

  6. Node.js C++ 插件学习指南

    Node.js插件(addons) Node.js 插件是用 C++ 编写的动态链接共享对象,可以使用 require() 函数加载到 Node.js 中,且像普通的 Node.js 模块一样被使用. ...

  7. uni-app ios 苹果真机运行

    首先我们准备苹果手机一台,数据线一根,然后连接到电脑. 1.电脑安装iTunes 软件,网址:http://soft.onlinedown.net/soft/279734.htm 安装完成之后打开iT ...

  8. LeetCode刷题191218

    好多天没有更新了,今天有空,刷一道. 算法第5题 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad"输出: ...

  9. 快速搭建用于测试的rtsp协议网络流媒体数据服务

    背景: 最近根据项目需求,在平台系统中加入了视频监控显示功能,但是限于没有提供真实可用的监控摄像头数据,通过EasyScreenLive快速搭建了一个rtsp的流媒体服务,下面将实现步骤分享给大家,为 ...

  10. [PHP] php使用event扩展的io复用测试

    先要安装event扩展,这样才可以使用libevent的事件机制 pecl install event 测试代码 //连接重用 //创建资源流的上下文 $context=stream_context_ ...