【BZOJ4945】[Noi2017]游戏 2-SAT
【BZOJ4945】[Noi2017]游戏
题解:2-SAT学艺不精啊!
这题一打眼看上去是个3-SAT?哎?3-SAT不是NPC吗?哎?这题x怎么只有8个?暴力走起!
因为x要么不是A要么不是B,所以直接2^8枚举所有x就行了。然后就变成了一个2-SAT问题。假设有两场游戏1,2,分别可以使用的地图为A1,A2,B1,B2,如果有一个限制是1 A 2 A,那么选A1就必须选A2,然后我这个沙茶就开开心心的拿了55分。
为什么不对?我建出来的图显然不对偶啊!考虑逆否命题,选A1就必须选A2,那么选B2就必须选B1啊!然后跑2-SAT+拓扑排序输出方案即可。
特别地,如果选A1就必须选A2,但是A1不能选,那么我们可以直接无视这个条件。如果选A1就必须选A2,但是A2不能选,那么A1也不能选, 于是就连一条A1->B1的边(你可以理解为这样以来,在反向图中B1的拓扑序在A1前面,所以会先选B1。但真正用意好像不是这个~)。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define P(A,B) ((B-1)*n+A)
using namespace std;
const int maxn=200010;
int n,D,m,sum,tot,top,cnt,flag;
int to[maxn],next[maxn],head[maxn],tt[maxn],nn[maxn],hh[maxn],op[maxn],ot[maxn];
int del[maxn],ins[maxn],dep[maxn],low[maxn],sta[maxn],bel[maxn],pos[10];
int pa[maxn],pb[maxn],pc[maxn],pd[maxn],color[maxn],d[maxn];
char str[maxn],c1[5],c2[5],ans[maxn];
queue<int> q;
void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void ADD(int a,int b)
{
tt[cnt]=b,nn[cnt]=hh[a],hh[a]=cnt++;
}
void tarjan(int x)
{
dep[x]=low[x]=++tot,ins[x]=1,sta[++top]=x;
for(int i=hh[x];i!=-1;i=nn[i])
{
int y=tt[i];
if(!dep[y]) tarjan(y),low[x]=min(low[x],low[y]);
else if(ins[y]) low[x]=min(low[x],dep[y]);
}
if(dep[x]==low[x])
{
int t;
sum++;
do
{
t=sta[top--],ins[t]=0,bel[t]=sum;
}while(t!=x);
}
}
void check()
{
memset(hh,-1,sizeof(hh));
memset(dep,0,sizeof(dep));
cnt=tot=sum=0;
int i,a,b,c;
for(i=1;i<=n;i++)
{
a=(str[i]-'a')*n+i,b=(a-1+n)%(3*n)+1,c=(b-1+n)%(3*n)+1;
del[a]=1,del[b]=del[c]=0;
op[b]=c,op[c]=b;
}
for(i=1;i<=m;i++)
{
a=pc[i]*n+pa[i],b=pd[i]*n+pb[i];
if(a==b||del[a]) continue;
if(pa[i]==pb[i]||del[b])
{
ADD(a,op[a]);
continue;
}
ADD(op[b],op[a]),ADD(a,b);
}
for(i=1;i<=3*n;i++) if(!del[i]&&!dep[i]) tarjan(i);
for(i=1;i<=3*n;i++)
{
if(del[i]) continue;
if(bel[op[i]]==bel[i]) return ;
else ot[bel[op[i]]]=bel[i],ot[bel[i]]=bel[op[i]];
}
flag=1;
}
void dfs(int x)
{
if(x==D+1)
{
check();
return ;
}
str[pos[x]]='a',dfs(x+1);
if(flag) return ;
str[pos[x]]='b',dfs(x+1);
}
void DFS(int x)
{
if(color[x]!=-1) return ;
color[x]=0,color[ot[x]]=1;
for(int i=head[x];i!=-1;i=next[i]) DFS(to[i]);
}
int main()
{
scanf("%d%d%s%d",&n,&D,str+1,&m);
int i,j,u;
for(i=1;i<=n;i++) if(str[i]=='x') pos[++pos[0]]=i;
for(i=1;i<=m;i++)
{
scanf("%d%s%d%s",&pa[i],c1,&pb[i],c2),pc[i]=c1[0]-'A',pd[i]=c2[0]-'A';
}
dfs(1);
if(!flag)
{
printf("-1");
return 0;
}
memset(head,-1,sizeof(head));
memset(color,-1,sizeof(color));
cnt=0;
for(i=1;i<=3*n;i++) if(!del[i])
{
for(j=hh[i];j!=-1;j=nn[j]) if(bel[tt[j]]!=bel[i]) d[bel[i]]++,add(bel[tt[j]],bel[i]);
}
for(i=1;i<=sum;i++) if(!d[i]) q.push(i);
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i])
{
d[to[i]]--;
if(!d[to[i]]) q.push(to[i]);
}
if(color[u]!=-1) continue;
DFS(ot[u]);
}
for(i=1;i<=3*n;i++) if(!del[i]&&color[bel[i]]==1) ans[(i-1)%n]=(i-1)/n+'A';
printf("%s",ans);
return 0;
}
【BZOJ4945】[Noi2017]游戏 2-SAT的更多相关文章
- [BZOJ4945][Noi2017]游戏 2-sat
对于所有的x,我们枚举他的地图类型,事实上我们只需要枚举前两种地形就可以覆盖所有的情况. 之后就变成了裸的2-sat问题. 对于一个限制,我们分类讨论: 1.h[u]不可选,跳过 2.h[v]不可选, ...
- [bzoj4945][Noi2017]游戏
题目大意:有$n$个位置,有三种数,每个位置只可以填一种数,$d(d\leqslant8)$个位置有三种选择,其他位置只有两种选择.有一些限制,表示第$i$个位置选了某种数,那么第$j$个位置就只能选 ...
- 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 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...
- 【bzoj4945】[Noi2017]游戏(搜索+2-sat)
bzoj 洛谷 题意: 现在有\(a,b,c\)三种车,每个赛道可能会存在限制:\(a\)表示不能选择\(a\)类型的赛车,\(b,c\)同理:\(x\)表示该赛道不受限制,但\(x\)类型的个数$\ ...
- 并不对劲的bzoj4945:loj2305:uoj317:p3825[NOI2017]游戏
题目大意 2-SAT,其中有\(d\)(\(d\leq 8\))个点是\(3-SAT\). 题解 枚举\(d\)个点不取三个中(假设三个为\(a,b,c\))的哪一个,然后整体变成做\(2-SAT\) ...
- bzoj3825 NOI2017 游戏
题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用一张地 ...
- [NOI2017]游戏(2-SAT)
这是约半年前写的题解了,就搬过来吧 感觉这是NOI2017最水的一题(当然我还是不会2333),因为是一道裸的2-SAT.我就是看着这道题学的2-SAT 算法一:暴力枚举.对于abc二进制枚举,对于x ...
随机推荐
- ios textfield如何设置,只能输入1.0-9.9内的数字,并实现时时监测效果
//byzqk- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range repla ...
- react 使用antd的多选功能做一个单选与全选效果
一个小而简单的单选全选功能,其实官网已经给出效果了,不过是我多做了些复合用法 addorupdatemodal.jsx import React from "react"; imp ...
- 连接mysql
1.nuget 所搜MySql.Data 2.appsettings.json { "ConnectionStrings": { "DefaultConnection& ...
- Codeforces Round #450 (Div. 2) A. Find Extra One【模拟/判断是否能去掉一个点保证剩下的点在Y轴同侧】
A. Find Extra One time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- 基于WPF系统框架设计(10)-分页控件设计
背景 最近要求项目组成员开发一个通用的分页组件,要求是这个组件简单易用,通用性,兼容现有框架MVVM模式,可是最后给我提交的成果勉强能够用,却欠少灵活性和框架兼容性. 设计的基本思想 传入数据源,总页 ...
- ArcObject开发,程序编译通过,但无法启动的解决
在ArcGIS 二次开发时,我们很容易就会忽略了,授权方面的问题,尤其是初学者.这方面的问题的解决,主要有: (1)在ArcGIS object控件出现的Form窗体,上添加License Contr ...
- 如何部署和运行Scut服务器及游戏:Windows篇
概述 Scut游戏引擎是一个永久免费的全脚本游戏服务器框架,采用MVC框架设计,简化数据库设计和编码工作:降低对开发人员的开发难度:同时提供了丰富的类库和API接口. 一. 安装环境 必须安装的 ...
- MyEclipse出错解决
错误信息: Deployment failure on Tomcat 6.x. Could not copy all resources to C:\Tomcat 6.0\webapps\JavaP ...
- WPF文字渲染相关的问题及解决
wpf中常常遇到各种和文字渲染有关的问题. 如今列举下现象和解决方式. (1) 现象: 文字大小不一.不在同一水平线. 不同字渲染成同一个字, 或者字体发虚 原因:微软雅黑字体对中文字符的渲染支 ...
- GIS可视化——热点格网图
一.简介 原理:按照格网大小将区域进行划分,由一个矩形格网替代当前范围内的数据,由格网中心数字代替格网的权重(可以为格网中数据的数量,数据某权重的平均值.最大值.最小值等), 由格网之间颜色的不同表达 ...