正题

题目链接:https://www.luogu.com.cn/problem/P3825


题目大意

nnn场比赛,对于场地aaa不能用赛车AAA(b,cb,cb,c以此类推),对于场地xxx可以用任何赛车。然后给定mmm条条件形如iIjJi\ I\ j\ Ji I j J表示在第iii场比赛使用赛车III的话那么必须在第jjj场比赛使用赛车JJJ。

求一组合法安排方案


解题思路

因为对于场地xxx我们有三种选择方法,所以这是一个3−SAT3-SAT3−SAT问题,无法计算。而因为xxx场地数量很少,我们可以枚举每个场地xxx使用哪辆车(是场地aaa还是场地bbb)即可。

然后就是很普通的2−SAT2-SAT2−SAT问题了,时间复杂度O(2dn)O(2^dn)O(2dn)


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#define p(n,k) (((n)-1)*6+(k)+1)
using namespace std;
// 0选a 1不选择a 2选择b 3不选择b 4选择c 5不选择c
const int N=5e4*6;
struct node{int to,next;
}a[N*8];
struct quee{int a,b,va,vb;
}q[N];
int n,d,m,tot,scc,cnt,ls[N];
int dfn[N],low[N],color[N];
bool ins[N];char s[N];
stack<int> S;
void addl(int x,int y,int w){if(w)addl(y,x,0);a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void tarjan(int x){dfn[x]=low[x]=++cnt;S.push(x);ins[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);else if(ins[y])low[x]=min(low[x],dfn[y]);}if(dfn[x]==low[x]){++scc;while(S.top()!=x){color[S.top()]=scc;ins[S.top()]=0;S.pop();}color[S.top()]=scc;ins[S.top()]=0;S.pop();}return;
}
bool solve(){memset(ls,0,sizeof(ls));memset(dfn,0,sizeof(dfn));cnt=scc=tot=0;for(int i=1;i<=n;i++){if(s[i]=='a'){addl(p(i,0),p(i,1),0);//不能选a addl(p(i,2),p(i,5),1);//选b不选c addl(p(i,4),p(i,3),1);//选c不选b }if(s[i]=='b'){addl(p(i,2),p(i,3),0);//不能选b addl(p(i,0),p(i,5),1);//选a不选c addl(p(i,4),p(i,1),1);//选c不选a }if(s[i]=='c'){addl(p(i,4),p(i,5),0);//不能选caddl(p(i,0),p(i,3),1);//选a不选baddl(p(i,2),p(i,1),1);//选b不选a }}for(int i=1;i<=m;i++){addl(p(q[i].a,q[i].va),p(q[i].b,q[i].vb),0);addl(p(q[i].b,q[i].vb+1),p(q[i].a,q[i].va+1),0);}for(int i=1;i<=n*6;i++)if(!dfn[i])tarjan(i);for(int i=1;i<=n;i++)if(color[p(i,0)]==color[p(i,1)]||color[p(i,2)]==color[p(i,3)]||color[p(i,4)]==color[p(i,5)]){return 0;}for(int i=1;i<=n;i++){if(color[p(i,0)]<color[p(i,1)])printf("A");else if(color[p(i,2)]<color[p(i,3)])printf("B");else if(color[p(i,4)]<color[p(i,5)])printf("C");}return 1;
}
int main()
{scanf("%d%d",&n,&d);scanf("%s",s+1);d=0;int wz[10];for(int i=1;i<=n;i++)if(s[i]=='x')wz[++d]=i;scanf("%d",&m);for(int i=1;i<=m;i++){int a,b,va,vb;char oa[3],ob[3];scanf("%d %s %d %s",&q[i].a,oa,&q[i].b,ob);if(oa[0]=='A')va=0;else q[i].va=(oa[0]=='B')?2:4;if(ob[0]=='A')vb=0;else q[i].vb=(ob[0]=='B')?2:4;}int MS=1<<d;for(int i=0;i<MS;i++){for(int j=1;j<=d;j++)s[wz[j]]='a'+((i>>j)&1);if(solve())return 0;}printf("-1");
}
/*
5 2
acxax
10
2 B 1 A
3 C 4 C
4 B 3 C
5 B 3 B
2 B 3 A
3 A 2 A
5 B 1 C
3 B 1 B
2 C 4 C
4 B 2 A
*/

P3825-[NOI2017]游戏【2-SAT】相关推荐

  1. P3825 [NOI2017]游戏

    P3825 [NOI2017]游戏 题目描述 小 L 计划进行n场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母A.B.C表示.地图一共有四 ...

  2. [NOI2017]游戏(2-SAT)

    这是约半年前写的题解了,就搬过来吧 感觉这是NOI2017最水的一题(当然我还是不会2333),因为是一道裸的2-SAT.我就是看着这道题学的2-SAT 算法一:暴力枚举.对于abc二进制枚举,对于x ...

  3. bzoj 4945: [Noi2017]游戏

    Description Solution 首先我们发现一个位置如果不是 \('x'\),那么就只有两种选择 而 \('x'\) 的个数小于等于 \(8\),直接枚举是哪个就好了 然后就是 \(2-sa ...

  4. 暑假训练-义乌(7.8-7.15)

    暑假训练 模拟赛 图表 数据 7.8(lxl) 7.9(lxl) 7.10(lxl) 7.11(lxl) 7.12(wls) 7.13(wls) 7.14(wls) 7.15(lfds) 训练 数据结 ...

  5. Luogu P4782 【模板】2-SAT 问题(2-SAT)

    P4782 [模板]2-SAT 问题 题意 题目背景 \(2-SAT\)问题模板 题目描述 有\(n\)个布尔变量\(x_1\sim x_n\),另有\(m\)个需要满足的条件,每个条件的形式都是&q ...

  6. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

  7. 一句话题解(20170801~20170125)

    8.1 bzoj 4720 noip2016 换教室 floyd预处理+期望(薛定谔的猫) bzoj 4318 OSU! 三次函数期望值 从一次.二次推得 8.2 bzoj 1076 状压+期望DP ...

  8. NOI2010~NOI2018选做

    [NOI2010] [NOI2010]海拔 高度只需要0/1,所以一个合法方案就是一个割,平面图求最小割. [NOI2010]航空管制 反序拓扑排序,每次取出第一类限制最大的放置,这样做答案不会更劣. ...

  9. 2-SAT问题的一种解法(简明易懂)

    2-sat即2元约束问题 下面不加证明地描述一种较优的解法: 为每个需要被判定的量建立true.false两个节点,方便起见称它们为互斥节点. 将约束条件抽象为代表推导关系的有向边. tarjan缩点 ...

  10. loj #2305. 「NOI2017」游戏

    #2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...

最新文章

  1. json-schema 简介
  2. MVC中实现 加载更多...
  3. 『Numpy』np.ravel()和np.flatten()
  4. 【问题记录】eclipse启动web项目时,spring会初始化两次
  5. u盘安装linux双系统6,用U盘安装Centos6.5 + Win7 双系统
  6. java中 inheritdoc,【Java】Javadoc的使用
  7. Leetcode-88:合并两个有序数组
  8. 千万不要错过...超级搞笑
  9. linux将汇编转为机器码,汇编语言 高级语言 机器语言 本地代码
  10. ORM中的Model与DDD中的DomainModel
  11. [03] Android系统亮度调节
  12. 力扣530. 二叉搜索树的最小绝对差(JavaScript)
  13. 用juniversalchardet解决爬虫乱码问题
  14. 用yacc编写的算术运算计算器_如何用纯机械实现乘除运算,这是个问题
  15. 机器学习算法_机器学习算法之PCA算法
  16. PIX 7.2 PAT
  17. Linux 入门常见命令大全-初学者必看
  18. c语言外心,下面说法正确的是( )A.三点确定一个圆B.外心在三角形的内部C.平...
  19. RDD转换为DataFrame的两种方式详解
  20. java 判断字符 不等于 或者_java中字符串不等于怎么判断

热门文章

  1. 5码默认版块_5个小众的生活学习类的宝藏App
  2. cgi备份还原和ghost有什么区别_手动GHOST还原重装系统详细教程
  3. linux下安装服务,linux下的软件服务安装管理
  4. 罗马数字转换成数字java_C趣味编程百例(31)将阿拉伯数字转换为罗马数字
  5. php网页连mysql_php - 如何在单个网页上连接多个MySQL数据库?
  6. 做流向图_各类型供热暖系统图大全,一饱眼福!
  7. python函数模块化教程_【软件测试教程】Python模块化以及内置模块的使用
  8. C++实现井字棋小游戏(写得不好,留作纪念!!!)
  9. 洛谷 P1506 拯救oibh总部-dfs染色法
  10. 辅助类BinaryTreeNode(二叉树节点)