Luogu 3825 [NOI2017]游戏
Luogu的spj现在挂了,要去其他OJ提交。
2-SAT
发现如果不考虑$x$的情况,这就成为一个2-SAT的裸题了,我们有$O(n + m)$的方法可以解决它。
那加上$x$的情况怎么弄……岂不是变成一个3-SAT。
滑稽吧,3-SAT已经被证明是一个完全NPC问题了……
再观察一下数据范围发现为$x$的点最多只有$8$个,那么我们思考一下(看一下题解)就会发现$x$的点取$a$或者$b$的情况其实就可以遍历到所有可行解了,所以直接取枚举这个$2^{d}$,然后$O(n + m)$地去检验它,时间复杂度$O(2^{d}(n + m))$。
连边方法(假设当前的条件是$x, c1, y, c2$):
1、如果第$x$场不能使用$x$,那么直接$continue$,这个条件显然没有影响。
2、如果第$x$场能使用$x$,第$y$场不能使用$y$,那么直接把$(x, true)$连向$(x, false)$,代表如果选了$(x, true)$就无解。
3、如果第$x$场可以使用$x$,第$y$场也可以使用$y$,那么按照套路连成一个对偶图,把$(x, true)$向$(y, true)$连边,同时把$(y, false)$向$(x, false)$连边。
关于$(x, true)$和$(x, false)$的记法,可以自己yy一下,要把$(x, true)$记为$x$, $(x, false)$记为$x + n$, 最后输出的时候对应回来就好。
Code:
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std; const int N = 2e5 + ; int n, m, K, pos[], tot, head[N];
int dfsc, dfn[N], low[N], top, sta[N], scc, bel[N];
char str[N];
bool vis[N]; struct Eedge {
int to, nxt;
} e[N << ]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} struct Restrain {
char c1, c2;
int x, y; inline void readIn() {
c1 = c2 = ;
read(x); for(c1 = getchar(); c1 != 'A' && c1 != 'B' && c1 != 'C'; c1 = getchar());
read(y); for(c2 = getchar(); c2 != 'A' && c2 != 'B' && c2 != 'C'; c2 = getchar());
} } a[N]; inline int id(int now, char c) {
if(str[now] == 'a') return c == 'C' ? now : now + n;
if(str[now] == 'b') return c == 'A' ? now : now + n;
if(str[now] == 'c') return c == 'B' ? now : now + n;
return ;
} inline int opp(int nowId) {
return nowId > n ? nowId - n : nowId + n;
} inline int min(int x, int y) {
return x > y ? y : x;
} void tarjan(int x) {
dfn[x] = low[x] = ++dfsc;
vis[x] = , sta[++top] = x;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
} else if(vis[y]) low[x] = min(low[x], dfn[y]);
} if(low[x] == dfn[x]) {
++scc;
for(; sta[top + ] != x; --top) {
vis[sta[top]] = ;
bel[sta[top]] = scc;
}
}
} inline bool solve() {
dfsc = tot = top = scc = ;
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(bel, , sizeof(bel));
memset(head, , sizeof(head)); for(int i = ; i <= m; i++) {
if(a[i].c1 + == str[a[i].x]) continue;
if(a[i].c1 == a[i].c2 && a[i].x == a[i].y) continue;
int p1 = id(a[i].x, a[i].c1), p2 = opp(p1);
int p3 = id(a[i].y, a[i].c2), p4 = opp(p3);
if(a[i].c2 + == str[a[i].y]) {
add(p1, p2);
continue;
}
add(p1, p3), add(p4, p2);
} for(int i = ; i <= * n; i++)
if(!dfn[i]) tarjan(i); for(int i = ; i <= n; i++)
if(bel[i] == bel[i + n]) return ; return ;
} inline void print() {
for(int i = ; i <= n; i++) {
if(bel[i] < bel[i + n]) {
if(str[i] == 'a') putchar('C');
if(str[i] == 'b') putchar('A');
if(str[i] == 'c') putchar('B');
} else {
if(str[i] == 'a') putchar('B');
if(str[i] == 'b') putchar('C');
if(str[i] == 'c') putchar('A');
}
}
exit();
} int main() {
read(n), read(K); scanf("%s", str + );
K = ;
for(int i = ; i <= n; i++)
if(str[i] == 'x') pos[++K] = i; /* for(int i = 1; i <= K; i++)
printf("%d ", pos[i]);
printf("\n"); */ read(m);
for(int i = ; i <= m; i++) a[i].readIn(); /* for(int i = 1; i <= m; i++)
printf("%d %c %d %c\n", a[i].x, a[i].c1, a[i].y, a[i].c2); */ for(int S = ; S < ( << K); S++) {
for(int i = ; i < K; i++)
if((S >> i) & ) str[pos[i + ]] = 'a';
else str[pos[i + ]] = 'b'; bool flag = solve();
if(flag) print();
} puts("-1");
return ;
}
Luogu 3825 [NOI2017]游戏的更多相关文章
- [Luogu P3825] [NOI2017] 游戏 (2-SAT)
[Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...
- 洛谷3825 [NOI2017]游戏 2-sat
原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...
- Luogu P3825 [NOI2017]游戏
这道题看上去NPC啊,超级不可做的样子. 我们先分析一下简单的情形:没有\(x\)地图 此时每个地图由于限制掉一种汽车,那么显然只会有两种选择. 再考虑到限制的情况,那么大致做法就很显然了--2-SA ...
- P3825 [NOI2017]游戏
题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...
- 【BZOJ4945】[Noi2017]游戏 2-SAT
[BZOJ4945][Noi2017]游戏 题目描述 题解:2-SAT学艺不精啊! 这题一打眼看上去是个3-SAT?哎?3-SAT不是NPC吗?哎?这题x怎么只有8个?暴力走起! 因为x要么不是A要么 ...
- [luogu]P1070 道路游戏[DP]
[luogu]P1070 道路游戏 题目描述小新正在玩一个简单的电脑游戏.游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针 ...
- BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...
- bzoj3825 NOI2017 游戏
题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用一张地 ...
- [NOI2017]游戏(2-SAT)
这是约半年前写的题解了,就搬过来吧 感觉这是NOI2017最水的一题(当然我还是不会2333),因为是一道裸的2-SAT.我就是看着这道题学的2-SAT 算法一:暴力枚举.对于abc二进制枚举,对于x ...
随机推荐
- 删除power by dedecms的方法
在include/dedesql.class.php文件,会发现最新的include/dedesql.class.php文件会多出第588到第592行的那几段代码,代码如下图: $arrs1 = ar ...
- ios9 3dtouch 博客
http://my.oschina.net/u/2340880/blog/511509#OSC_h3_3
- <Linux内核源码>内存管理模型
题外语:本人对linux内核的了解尚浅,如果有差池欢迎指正,也欢迎提问交流! 首先要理解一下每一个进程是如何维护自己独立的寻址空间的,我的电脑里呢是8G内存空间.了解过的朋友应该都知道这是虚拟内存技术 ...
- FOJ 2232 匈牙利算法找二分图最大匹配
题目链接 简单理解匈牙利算法 简单理解二分图 尽量让每一个随从击败一个对手且随从全部存活,关键是为每一个随从找对手(递归过程),"腾". #include<iostream& ...
- 随意谈谈tcp
tcp作为四层中可靠到传输协议,为上层协议提供了字节流的可靠到传输,之所以能做到可靠主要因为以下几点: 1.流与分段:流即字节流,计算机处理程序时一般以字节为单位,如果上层协议接收到到是字节流并且跟发 ...
- JavaWeb中文件的上传和下载
JavaWeb中文件的上传和下载 转自: JavaWeb学习总结(五十)——文件上传和下载 - 孤傲苍狼 - 博客园https://www.cnblogs.com/xdp-gacl/p/4200090 ...
- DELPHI中四种EXCEL访问技术实现
一.引言 EXCEL在处理中文报表时功能非常强大,EXCEL报表访问也是信息系统开发中的一个重要内容,本文总结以往开发中所用到的几中EXCEL文件访问方法,在实际工作中也得到了很好的验证,本文列举了其 ...
- elasticsearch监控平台cerebro-0.8.3 相关操作
上面这个平台是cerebro-0.8.3 在github上找就有了 #################### GET /hnscan_source_o_comm_drv_bad_bhv_occur/ ...
- LOJ2722 「NOI2018」情报中心
「NOI2018」情报中心 题目描述 C 国和D 国近年来战火纷飞. 最近,C 国成功地渗透进入了D 国的一个城市.这个城市可以抽象成一张有$n$ 个节点,节点之间由$n - 1$ 条双向的边连接的无 ...
- 【VS】VS开发中遇到的问题的总结
1. VS中经常会出现无法解析的外部符号,还有LINK ERROR 2019等 这类问题如果检查代码没有错误,很大概率就是lib文件错误.调试程序找出问题函数,再找出问题函数使用到的lib文件,在项 ...