题解 洛谷 P6378 【[PA2010]Riddle】
首先不难看出对于本题的点与点之间的限制关系,我们可以考虑用\(2-SAT\)来解决,通过从状态\(x\)向状态\(y\)连一条有向边表示若状态\(x\)存在,那么状态\(y\)必须存在。
接下来的处理中,\(x\)表示点\(x\)被选为关键点,\(x^\prime\)表示点\(x\)没有选为关键点,\(x \longrightarrow y\)表示两个状态之间连一条有向边。
对于每条边至少有一个端点是关键点这一限制,若边两端为\(x\)和\(y\),那么直接进行\(x^\prime \longrightarrow y\ ,\ y^\prime \longrightarrow x\)即可。
处理使得每个部分恰有一个关键点这一限制时,发现要进行像一个点向该部分中除它以外的所有点连边的操作,这样的话,边数会达到\(n^2\)级别,这是不可以接受的,所以要考虑优化建图。
对于每个点,我们这里在其所在的部分中考虑,每个点用\(a_i\)来表示,再对其新增一个状态\(pre_i\),表示在该部分中前\(i\)个点是否有点被选为关键点。
连边时我们可以进行以下的操作:
\(a_i \longrightarrow pre_{a_i}\ ,\ pre_{a_i}^\prime \longrightarrow a_i^\prime\)
$pre_{a_{i-1}} \longrightarrow pre_{a_i}\ ,\ pre_{a_i}^\prime \longrightarrow pre_{a_{i-1}}^\prime\ $
\(\ pre_{a_{i-1}} \longrightarrow a_i^\prime\ ,\ a_i \longrightarrow pre_{a_{i-1}}^\prime\)
通过这样的前缀优化建图,就不用再连那么多边了,同时题目的限制条件也都可以满足。
具体实现细节看代码吧。
\(code:\)
#include<bits/stdc++.h>
#define p1(x) x
#define p0(x) x+n
#define pre1(x) x+2*n
#define pre0(x) x+3*n
#define maxn 8000010
using namespace std;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m,k,dfn_cnt,co_cnt,top;
int dfn[maxn],low[maxn],co[maxn],st[maxn],a[maxn];
bool vis[maxn];
struct edge
{
int to,nxt;
}e[maxn];
int head[maxn],edge_cnt;
void add(int from,int to)
{
e[++edge_cnt]=(edge){to,head[from]};
head[from]=edge_cnt;
}
void tarjan(int x)
{
dfn[x]=low[x]=++dfn_cnt;
st[++top]=x,vis[x]=true;
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])
{
co_cnt++;
int now;
do
{
now=st[top--];
vis[now]=false;
co[now]=co_cnt;
}while(now!=x);
}
}
bool check()
{
for(int i=1;i<=4*n;++i)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;++i)
if(co[p1(i)]==co[p0(i)]||co[pre1(i)]==co[pre0(i)])
return false;
return true;
}
int main()
{
read(n),read(m),read(k);
for(int i=1;i<=m;++i)
{
int x,y;
read(x),read(y);
add(p0(x),p1(y)),add(p0(y),p1(x));
}
for(int i=1;i<=k;++i)
{
int w;
read(w);
for(int j=1;j<=w;++j)
read(a[j]),add(p1(a[j]),pre1(a[j])),add(pre0(a[j]),p0(a[j]));
for(int j=2;j<=w;++j)
{
add(pre1(a[j-1]),pre1(a[j])),add(pre0(a[j]),pre0(a[j-1]));
add(pre1(a[j-1]),p0(a[j])),add(p1(a[j]),pre0(a[j-1]));
}
}
if(check()) puts("TAK");
else puts("NIE");
return 0;
}
题解 洛谷 P6378 【[PA2010]Riddle】的更多相关文章
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 题解-洛谷P4229 某位歌姬的故事
题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
- 题解-洛谷P4859 已经没有什么好害怕的了
洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...
- 题解-洛谷P5217 贫穷
洛谷P5217 贫穷 给定长度为 \(n\) 的初始文本 \(s\),有 \(m\) 个如下操作: \(\texttt{I x c}\),在第 \(x\) 个字母后面插入一个 \(c\). \(\te ...
- 题解 洛谷 P2010 【回文日期】
By:Soroak 洛谷博客 知识点:模拟+暴力枚举 思路:题目中有提到闰年然后很多人就认为,闰年是需要判断的其实,含有2月29号的回文串,前四位是一个闰年那么我们就可以直接进行暴力枚举 一些小细节: ...
- 题解 洛谷P2158 【[SDOI2008]仪仗队】
本文搬自本人洛谷博客 题目 本文进行了一定的更新 优化了 Markdown 中 Latex 语句的运用,加强了可读性 补充了"我们仍不曾知晓得 消失的 性质5 ",加强了推导的严谨 ...
随机推荐
- 2、尚硅谷_SSM高级整合_使用ajax操作实现页面的查询功能
16.尚硅谷_SSM高级整合_查询_返回分页的json数据.avi 在上一章节的操作中我们是将PageInfo对象存储在request域中,然后list页面解析request域中的对象实现信息的显示. ...
- django 中间键 csrf 跨站请求伪造
django中间件和auth模块 Django中间件 由django的生命周期图我们可以看出,django的中间件就类似于django的保安,请求一个相应时要先通过中间件才能到达django后端( ...
- Jmeter系列(30)- 详解 JDBC Request
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 前言 JDBC Request 主要是 ...
- Pytorch入门——手把手带你配置云服务器环境
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天这篇是Pytorch专题第一篇文章. 大家好,由于我最近自己在学习Pytorch框架的运用,并且也是为了响应许多读者的需求,推出了这个P ...
- C#数据结构与算法系列(十八):冒泡排序算法(BubbleSort)
1.介绍 冒泡排序的基本思想就是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底的气泡一样逐渐向上冒泡. 因为排序的 ...
- Python实用笔记 (6)函数
绝对值 >>> abs(100) 100 >>> abs(-20) 20 max()可以接收任意多个参数,并返回最大的那个: >>> max(1, ...
- vue全家桶(4.2)
5.2.使用vuex重构上面代码 Vuex是什么?官方定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测 ...
- 每日一题 - 剑指 Offer 54. 二叉搜索树的第k大节点
题目信息 时间: 2019-07-04 题目链接:Leetcode tag:二叉搜索树 中序遍历 递归 难易程度:中等 题目描述: 给定一棵二叉搜索树,请找出其中第k大的节点. 示例1: 输入: ro ...
- CSS 3中-webkit-, -moz-, -o-, -ms-这些私有前缀的含义和兼容
css3作为页面样式的表现语言,增加了很多新的属性,但是部分css3属性在一些浏览器上还处于试验阶段,所以为了有效的显示css3的样式,对应不同的浏览器内核需要不同的前缀声明,例如: -moz- :F ...
- 常用API - Scanner、Random、ArrayList
API 概述 API(Application Programming Interface),应用程序编程接口. Java API是一本程序员的 字典 ,是JDK中提供给我们使用的类的说明文档. 这些类 ...