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. 【5000 Stars 福利】微信接口动态 WebApi 使用说明

    前言 作为中国 C# 开源项目中 Watch/Star/Fork 最高的项目之一,Senparc.Weixin SDK  凝聚了盛派微信团队持续7年的付出,和大量开发者的无私贡献,以及数万开发者的使用 ...

  2. SpringBoot 并发登录人数控制

    通常系统都会限制同一个账号的登录人数,多人登录要么限制后者登录,要么踢出前者,Spring Security 提供了这样的功能,本文讲解一下在没有使用Security的时候如何手动实现这个功能 dem ...

  3. Dockerfile编写

    Dockerfile 是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建编写命令: 1.FROM作用:声明使用哪个基础镜像格式:FROM IMA ...

  4. 集合 set方法

    集合 number = {1, 2, 4} # 添加元素到集合 number.add(100) print(number) # 从集合中删除 number.remove(2) print(number ...

  5. Nginx:反向代理

    与众不同的生活方式很累人呢,因为找不到借口     在上一章节中,我们以及了解到正向.反向代理.负载均衡和动静分离的基本概念,安装教程,而在本节中将会了解到在 本文要点: 1.理清概念 2.Linux ...

  6. 附007.Kubernetes ABAC授权

    一 ABAC 1.1 ABAC授权 基于属性的访问控制(ABAC)定义了访问控制范例,通过使用将属性组合在一起的策略向用户授予访问权限. 使用--authorization-policy-file=S ...

  7. P3747 [六省联考2017]相逢是问候

    题意 如果对一个数操作\(k\)次,那么这个数会变成\(c^{c^{...^{a_i}}}\),其中\(c\)有\(k\)个. 根据P4139 上帝与集合的正确用法这道题,我们可以知道一个数不断变为自 ...

  8. 关于python的中国历年城市天气信息爬取

    一.主题式网络爬虫设计方案(15分)1.主题式网络爬虫名称 关于python的中国城市天气网爬取 2.主题式网络爬虫爬取的内容与数据特征分析 爬取中国天气网各个城市每年各个月份的天气数据, 包括最高城 ...

  9. 【GUI】基于V7开发板的裸机和各种RTOS版本的emWin程序模板,支持硬件JPEG,已发布(2019-05-26)

    说明: 1.MDK请使用5.26及其以上版本,IAR请使用8.30及其以上版本. 2.修正了ST提供的部分驱动设计不合理的地方. 3.原创实现硬件JPEG添加到emWin中,实现简单,全程使用SDRA ...

  10. vscode 格式化代码 与 eslint 有冲突的问题解决

    项目中配置了eslint后,在使用vue界面里格式化的时候总是不一致.然后在配置中加了配置也无效(File - Preference - Setting) 查了下原因是在vue开发的时候我们一般都安装 ...