~~~题面~~~

题解:

  首先观察到,如果没有x的话,这就是一个2-sat问题。

  建图方式:对于限制d1 c1 d2 c2,其中d1, d2分别代表比赛编号,c1, c2代表出场的赛车。

  1,如果d1不能选c1,那么该限制是不会起到作用的,所以不连边。

  2,否则如果d2不能选c2,那么意味这d1-c1不能被选,所以连d1-c1 --- > d1-c2的边,表示必须取d1-c2。

  3,否则都可以选,所以连d1-c1 ---> d2-c2 , d1-c2 ---> d2-c1.

  跑tarjan求强连通分量即可。

  

  那么有x应该怎么做?

  观察到对于一组数据,x最多有8场,所以3^8枚举每场x的比赛是abc中的哪种(不选哪辆车),然后在跑2-sat即可。

  这里输出方案可以不用反向建边+拓扑排序,因为栈是后进先出,所以先出栈的点刚好是反向建边+拓扑排序后先遇到的点,因此只需要记录每个点所在的联通块编号,然后对于每场比赛选择联通块编号小的方案输出即可。

  题目数据极水,A了也不一定是正确代码,请特别注意检查代码正确性。(如果你发现我有哪里错了也可以告诉我QAQ)

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 300100
#define ac 1000000 int n, d, timer, all, m;
int s[AC], dfn[AC], low[ac], belong[ac], d1[AC], c1[AC], d2[AC], c2[AC];
int sta[AC], top;
int Head[AC], Next[ac], date[ac], tot;
char ss[AC];
bool flag, z[AC]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = * x + c - '', c = getchar();
return x;
} inline void upmin(int &a, int b)
{
if(b < a) a = b;
} inline void add(int f, int w)
{
date[++tot] = w, Next[tot] = Head[f], Head[f] = tot;
//printf("%d ---> %d\n", f, w);
} void tarjan(int x)
{
int now;
dfn[x] = low[x] = ++ timer, sta[++top] = x, z[x] = true;
for(R i = Head[x]; i; i = Next[i])
{
now = date[i];
if(!dfn[now])
{
tarjan(now);
upmin(low[x], low[now]);
}
else if(z[now]) upmin(low[x], low[now]);//已经出栈的无需考虑
}
if(low[x] == dfn[x])
{
++all;
while()
{
now = sta[top--], belong[now] = all, z[now] = false;//标记出栈
if(now == x) break;
}
}
} void init()
{
tot = all = timer = ;
memset(Head, , sizeof(Head));
memset(dfn, , sizeof(dfn));
memset(z, , sizeof(z));
} inline int get(int x, int color)
{
if(s[x] == color) return ;//不合法
if(s[x] == ) return x * + color - ;
else if(s[x] == ) return x * + ((color == ) ? : );
else return x * + color - ;
} void build()
{
init();
for(R i = ; i <= m; i ++)
{
int x = get(d1[i], c1[i]), y = get(d2[i], c2[i]);
if(x)
{
if(y) add(x, y), add(y ^ , x ^ );
else add(x, x ^ );
}
}
int b = n * + ;
for(R i = ; i <= b; i ++)
if(!dfn[i]) tarjan(i);
for(R i = ; i <= b; i += )//error !!!到b
if(belong[i] == belong[i ^ ]) return ;
for(R i = ; i <= n; i ++)
{
int x = i * ;
if(s[i] == ) putchar(belong[x] < belong[x ^ ] ? 'B' : 'C');
else if(s[i] == ) putchar(belong[x] < belong[x ^ ] ? 'A' : 'C');
else putchar(belong[x] < belong[x ^ ] ? 'A' : 'B');
}
flag = true;
} void pre()
{
char ch;
n = read(), d = read();
scanf("%s", ss + );
for(R i = ; i <= n; i ++)
if(ss[i] != 'x') s[i] = ss[i] - 'a' + ;
m = read();
for(R i = ; i <= m; i ++)
{
d1[i] = read(), cin >> ch, c1[i] = ch - 'A' + ;
d2[i] = read(), cin >> ch, c2[i] = ch - 'A' + ;
}
} void dfs(int x)
{
if(flag) return ;
if(x > n)
{
build();
return ;
}
if(!s[x])
{
s[x] = , dfs(x + );
s[x] = , dfs(x + );
s[x] = , dfs(x + );
s[x] = ;
}
else dfs(x + );
} int main()
{
freopen("in.in","r",stdin);
pre();
dfs();
if(!flag) printf("-1");
fclose(stdin);
return ;
}

[NOI2017]游戏 2-sat的更多相关文章

  1. P3825 [NOI2017]游戏

    题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...

  2. 【BZOJ4945】[Noi2017]游戏 2-SAT

    [BZOJ4945][Noi2017]游戏 题目描述 题解:2-SAT学艺不精啊! 这题一打眼看上去是个3-SAT?哎?3-SAT不是NPC吗?哎?这题x怎么只有8个?暴力走起! 因为x要么不是A要么 ...

  3. [Luogu P3825] [NOI2017] 游戏 (2-SAT)

    [Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...

  4. bzoj3825 NOI2017 游戏

    题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用一张地 ...

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

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

  6. NOI2017 [NOI2017]游戏 【2-sat】

    题目 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用 ...

  7. bzoj 4945: [Noi2017]游戏

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

  8. [NOI2017]游戏

    题目描述 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 题解 如果说没有x的话,那么每一局只能有两种选择,可以描述为是/非,每条限制也可以 ...

  9. 洛谷3825 [NOI2017]游戏 2-sat

    原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...

  10. Luogu3825 NOI2017 游戏 2-SAT

    传送门 第一眼看上去似乎是一个3-SAT问题 然而\(d \leq 8\)给我们的信息就是:暴力枚举 枚举\(x\)型地图变成\(a\)型地图还是\(b\)型地图(实际上不要枚举\(c\),因为\(a ...

随机推荐

  1. 配置Echarts大全

    由于项目中需要用到Echarts,最近研究了一个星期.网上的教程也挺多的.磕磕碰碰的,难找到合适的例子.都说的马马虎虎.不废话了.开始. 这种上下排列的... 还有这种地图的.(如下) 还有就是配置的 ...

  2. redis之哨兵(Sentinel)

    Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能. 而 ...

  3. lnmp配置支持thinkphp和nginx路由url重写

    ThinkPHP3.2.3项目放到lnmp环境之后只能打开首页,或者通过传参方式打开控制器,否则就一直显示404页面.搞了一上午,终于解决了 step1: 修改php.ini cgi.fix_path ...

  4. zabbix使用iostat命令参数监控磁盘性能

    iostat命令 先说一个坑把,在开始监控的时候使用命令iostat -dtkx,得到的结果看上去没问题,但是在web监控窗口数据就说不变动,为啥呢,因为iostat这个命令得到的第一个数据始终是磁盘 ...

  5. Scrapy进阶

    当我们使用scrapy框架爬取网站的时候,我们会有一个入口的url,一个名为start_urls,我们爬取的第一个网页是从这一开始的. 需求: 现在我们有一个这样的需求,比如说我们对起始的URL有一个 ...

  6. 计蒜客-----跳跃游戏(C语言)

    /********************************************************给定一个非负整数数组,假定你的初始位置为数组第一个下标.数组中的每个元素代表你在那个位 ...

  7. JavaSE基础复习---1---2018/9/27

    2018/9/27 JavaSE学习笔记-1 目录: Java的起源 Java语言概述 1.Java的起源 现代编程语言的发展,大致可以理解为,机器码语言---汇编语言---C语言---C++语言-- ...

  8. R语言学习笔记(六): 列表及数据框的访问

    List R语言中各组件的名称叫做标签(tags),访问列表有3种方法: j$salary 通过标签名字访问,只要不引起歧义,可以只写出前几个字母. j[['sal']] 夹在两个中括号时引号里的标签 ...

  9. SQL 公用表表达式(CTE)

    1.概念 公用表表达式(Common Table Expression)是SQL SERVER 2005版本之后引入的一个特性.CTE可以看作是一个临时的结果集,可以在接下来的一个SELECT,INS ...

  10. linux ln 建立软链接-- 基于dubbo-zookeeper服务的 服务jar 引用公共的 lib

    对于ln命令网上有很多的教程,这里不再复述, 其基本目的是:多个文件夹公用一个文件夹的里的文件. 其基本命令格式: ln [option] source_file dist_file (source_ ...