bzoj 4945: [Noi2017]游戏
Description
Solution
首先我们发现一个位置如果不是 \('x'\),那么就只有两种选择
而 \('x'\) 的个数小于等于 \(8\),直接枚举是哪个就好了
然后就是 \(2-sat\) 连边:
设一个点 \(i\) 的对立点为 \(i'\)
如果 \(a[i]=h[i]\),那么就可以直接忽略这个限制
如果 \(a[j]=h[j]\),那么 \(i\) 就不能选 \(a[i]\),为了保证这个限制直接连边 \((i,i')\) 就好了
如果上述两种情况都不是,那么直接连 \((i,j),(j',i')\) 就好了
值得注意的是:
\(2-sat\) 如果没有字典序最小的要求,可以直接 \(tarjan\) \(O(n)\) 的判断是否合法
方法就是判断对立点是否在同一强连通分量里即可
输出方案(拓扑排序贪心):
正向贪心会有后效性
把缩点之后的 \(DAG\) 的边反向,发现一个点 \(i\) 选了之后,拓扑序在 \(i'\) 之后的点就都不可以选了
每一次选了 \(i\) 之后,就把 \(i'\) 打上标记即可,就不拿有标记的点删边了
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n,D,m,lis[N],fr[N],tr[N];char s[N],a[N],b[N];
int head[N],nxt[N*2],to[N*2],num=1,in[N];
inline void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
int dfn[N],low[N],DFN=0,st[N],top,sum,be[N];bool inst[N],vis[N],fc[N];
vector<int>v[N],sc[N];vector<int>::iterator it;
inline void Clear(){
num=1;DFN=sum=top=0;
for(register int i=0;i<N;i++)
vector<int>().swap(sc[i]),head[i]=low[i]=dfn[i]=inst[i]=0;
}
inline int id(int i,char j){
if(s[i]=='a'){if(j=='b')return i;return i+n;}
if(s[i]=='b'){if(j=='a')return i;return i+n;}
if(j=='a')return i;return i+n;
}
inline int f(int x){return x>n?x-n:x+n;}
inline void tarjan(int x){
low[x]=dfn[x]=++DFN;inst[x]=1;st[++top]=x;
for(int i=head[x],u;i;i=nxt[i]){
if(!dfn[u=to[i]])tarjan(u),low[x]=min(low[x],low[u]);
else if(inst[u])low[x]=min(low[x],dfn[u]);
}
if(low[x]==dfn[x]){
int v;sum++;
do{
v=st[top--];be[v]=sum;inst[v]=0;
sc[sum].push_back(v);
}while(top && v!=x);
}
}
inline void Cliear(){
for(register int i=0;i<N;i++)
vector<int>().swap(v[i]),in[i]=vis[i]=fc[i]=0;
}
inline void solve(){
Clear();
for(int i=1;i<=m;i++){
if(s[fr[i]]==a[i])continue;
if(s[tr[i]]==b[i])link(id(fr[i],a[i]),f(id(fr[i],a[i])));
else{
int x=id(fr[i],a[i]),y=id(tr[i],b[i]);
link(x,y);link(f(y),f(x));
}
}
for(int i=1,li=n*2;i<=li;i++)if(!dfn[i])tarjan(i);
for(int i=1;i<=n;i++)if(be[i]==be[i+n])return ;
Cliear();
for(int i=1,li=n*2;i<=li;i++)
for(int j=head[i];j;j=nxt[j]){
int u=to[j];
if(be[u]==be[i])continue;
v[be[u]].push_back(be[i]);in[be[i]]++;
}
queue<int>Q;
for(int i=1;i<=sum;i++)if(!in[i])Q.push(i);
while(!Q.empty()){
int x=Q.front();Q.pop();
if(vis[x])continue;fc[x]=1;
for(it=sc[x].begin();it!=sc[x].end();++it)vis[be[f(*it)]]=1;
for(it=v[x].begin();it!=v[x].end();++it)
if(!(--in[*it]))Q.push(*it);
}
for(int i=1;i<=n;i++){
if(fc[be[i]]){
if(s[i]=='a')putchar('B');
else putchar('A');
}
else{
if(s[i]=='c')putchar('B');
else putchar('C');
}
}
exit(0);
}
inline void dfs(int x){
if(x==D+1){solve();return ;}
s[lis[x]]='a';dfs(x+1);
s[lis[x]]='b';dfs(x+1);
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
scanf("%d%d%s",&n,&D,s+1);
for(int i=1,j=0;i<=n;i++)if(s[i]=='x')lis[++j]=i;
scanf("%d",&m);char p1[2],p2[2];
for(int i=1;i<=m;i++){
scanf("%d%s%d%s",&fr[i],p1,&tr[i],p2);
a[i]=p1[0]+32;b[i]=p2[0]+32;
}
dfs(1);
puts("-1");
return 0;
}
bzoj 4945: [Noi2017]游戏的更多相关文章
- BZOJ 4945 NOI2017 游戏 搜索+2-SAT
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4945 分析: 首先考虑没有x的情况,发现有一个明显的推理模型,容易看出来可以用2-SAT ...
- 【刷题】BZOJ 4945 [Noi2017]游戏
Description http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf Solution 字符串里的'x'看起来很烦,于是考虑枚举这些'x' ...
- 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 P3825] [NOI2017] 游戏 (2-SAT)
[Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...
- BZOJ 4945 UOJ #317 NOI2017 游戏 2-SAT 拓扑排序
http://uoj.ac/problem/317 https://www.lydsy.com/JudgeOnline/problem.php?id=4945 我现在的程序uoj的额外数据通过不了,b ...
- [BZOJ]1059 矩阵游戏(ZJOI2007)
虽然说是一道水题,但小C觉得还是挺有意思的,所以在这里mark一下. Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N*N黑白 ...
- bzoj 3875 骑士游戏 - spfa - 动态规划
Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,J ...
- BZOJ 1854: [Scoi2010]游戏 无向图判环
题目链接: 题目 1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MB 问题描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装 ...
随机推荐
- C语言第四次作业-嵌套作业
一.PTA实验作业 题目1:7-4 换硬币 1. 本题PTA提交列表 2.设计思路 第一:定义三个整型变量f,t,o,分别代表五分,两分,一分的数量 第二:输入待换金额x 第三:令f=x/5;t=x/ ...
- Beta项目复审
Beta项目复审 复审人:张宇光 所属团队:MyGod 团队成员:程环宇.王田路.张芷祎.张宇光.王婷婷 团队排名: SW_HW4-team团队 hyw-team团队 Java-Team团队 C++团 ...
- 1013团队Beta冲刺day5
项目进展 李明皇 今天解决的进度 服务器端还未完善,所以无法进行联动调试.对页面样式和逻辑进行优化 明天安排 前后端联动调试 林翔 今天解决的进度 完成维护登录态,实现图片上传,微信开发工具上传图片不 ...
- 《Language Implementation Patterns》之访问&重写语法树
每个编程的人都学习过树遍历算法,但是AST的遍历并不是开始想象的那么简单.有几个因素会影响遍历算法:1)是否拥有节点的源码:2)是否子节点的访问方式是统一的:3)ast是homogeneous或het ...
- PYTHON 词云
#!/usr/bin/env python # -*- coding:utf-8 -*- import matplotlib.pyplot as plt from wordcloud import W ...
- OptaPlanner - 把example运行起来(运行并浅析Cloud balancing)
经过上面篇长篇大论的理论之后,在开始讲解Optaplanner相关基本概念及用法之前,我们先把他们提供的示例运行起来,好先让大家看看它是如何工作的.OptaPlanner的优点不仅仅是提供详细丰富的文 ...
- python 常用算法学习(2)
一,算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求 ...
- mui 页面无法下滑拖拽 主要体现在华为手机浏览器
项目做到中期遇到一个问题,华为手机有些页面显示不全且无法下滑. 因为之前一直用的Google浏览器的模拟模式进行开发和调试的,一直未发现这个问题. 刚开始 选用mui的下拉刷新上拉加载的方式来进行页面 ...
- C语言Linix服务器网络爬虫项目(一)项目初衷和网络爬虫概述
一.项目初衷和爬虫概述 1.项目初衷 本人的大学毕设就是linux上用c写的一个爬虫,现在我想把它完善起来,让他像一个企业级别的项目.为了重复发明轮子来学习轮子的原理,我们不使用第三方框架(这里是说的 ...
- 在bootstrap中让竖向排列的输入框水平排列
在bootstrap中可以使用自带的样式标记来控制样式,但是同时可以利用最原始的css样式来解决达到需求 如下所示可以看出来两个inline-block就可以使得两个水平排列 block和inline ...