【BZOJ】3495: PA2010 Riddle 2-SAT算法
【题意】有n个城镇被分成了k个郡,有m条连接城镇的无向边。要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都。n,m,k<=10^6。
【算法】2-SAT,前后缀优化建图
【题解】每个城镇只有作为首都和不是首都两种选项,即2-sat问题。
2-sat问题中所有边必须加反向边,下面过程忽略反向边。
对于一条边(x,y),如果x是0,那么y必须是1,即x-y'。(y-x'是反向边,考虑的时候忽略)
但是一个郡只有一个首都有点烦,有一种套路叫前后缀优化建图。
对于每个点x,假设一个点x+n,表示编号<=x的和x同在一个郡的点中是否有首都。
假设x和y是同一个郡的相邻编号点(y>x),那么:
1.前缀:(x+n)' - (y+n)'
2.修改:x' - (x+n)'
3.只有一个首都:(x+n)' - y
所以n*4个点和n*8条边,进行2-sat。
复杂度O(M),M=(m+3*n)*2。
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
int s=,t=;char c;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=;
int n,m,K,first[maxn],tot,c,B[],C[];
bool mark[maxn];
struct edge{int v,from;}e[maxn*];////
void insert(int u,int v){
tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;
tot++;e[tot].v=u^;e[tot].from=first[v^];first[v^]=tot;
}
int dfsnum=,TOT,top,dfn[maxn],low[maxn],st[maxn],belong[maxn];
void tarjan(int x){
dfn[x]=low[x]=++dfsnum;
st[++top]=x;
for(int i=first[x];i;i=e[i].from)if(!dfn[e[i].v]){
tarjan(e[i].v);
low[x]=min(low[x],low[e[i].v]);
}else if(!belong[e[i].v])low[x]=min(low[x],dfn[e[i].v]);
if(low[x]==dfn[x]){
TOT++;
while(st[top]!=x)belong[st[top--]]=TOT;
belong[st[top--]]=TOT;
}
}
int main(){
n=read();m=read();K=read();
for(int i=;i<=m;i++){
int u=read()-,v=read()-;
insert(u<<,v<<|);
}
for(int i=;i<n;i++)insert(i<<|,(i+n)<<|);///
for(int k=;k<=K;k++){
int w=read(),p,pre=read()-;B[pre]=k;
for(int i=;i<=w;pre=p,i++){
p=read()-;B[p]=k;
insert((pre+n)<<|,(p+n)<<|);
insert((pre+n)<<|,p<<);
}
}
for(int i=;i<n*;i+=){
if(!dfn[i])tarjan(i);
if(!dfn[i^])tarjan(i^);
if(belong[i]==belong[i^]){printf("NIE");return ;}
}
printf("TAK");
return ;
}
从这道题开始,我知道了一件事:理论复杂度O(nm)的DFS版2-sat是可以无视随机被卡TLE的。
嘤嘤嘤T_T。
【BZOJ】3495: PA2010 Riddle 2-SAT算法的更多相关文章
- BZOJ.3495.[PA2010]Riddle(2-SAT 前缀优化建图)
题目链接 每个城市要么建首都要么不建,考虑2-SAT 这样一个国家内城市两两连边是很显然的,但是边数为O(n^2) 每个国家中仅有一个建首都,考虑新建前缀S[i]=1/0这2n个点表示当前国家的[1, ...
- 【刷题】BZOJ 3495 PA2010 Riddle
Description 有n个城镇被分成了k个郡,有m条连接城镇的无向边. 要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都. Input 第一行有三个整数,城镇数n(1<=n& ...
- 3495: PA2010 Riddle 2-sat 前缀优化
3495: PA2010 Riddle 2-sat 前缀优化 链接 bzoj 思路 不想说啥了,看hwim的吧,我去睡觉了zZ. 代码 /******************************* ...
- 3495: PA2010 Riddle
3495: PA2010 Riddle 链接 分析: 每个点要么建首都,要么不建,并且一个点建了,会导致一些点不能建.所以可以考虑2-sat. 但是如果在每个郡里两两连边,边数是n^2的. 考虑用前缀 ...
- 【BZOJ】3495: PA2010 Riddle
题意 \(n(1 \le n \le 1000000)\)个城市,\(k(1 \le k \le n)\)个国家,\(m(1 \le m \le 1000000)\)条边.要求每个国家有且仅有一个首都 ...
- 【bzoj 3495】PA2010 Riddle
Description 有n个城镇被分成了k个郡,有m条连接城镇的无向边.要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都. Input 第一行有三个整数,城镇数n(1<=n&l ...
- Bzoj 1562: [NOI2009]变换序列 匈牙利算法,二分图匹配
题目: http://cojs.tk/cogs/problem/problem.php?pid=409 409. [NOI2009]变换序列 ★★☆ 输入文件:transform.in 输出文 ...
- BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法
标题效果:给定的长度m数字字符串s.求不包括子s长度n数字串的数目 n<=10^9 看这个O(n)它与 我们不认为这 令f[i][j]长度i号码的最后的字符串j位和s前者j数字匹配方案 例如,当 ...
- BZOJ 1085: [SCOI2005]骑士精神(A*算法)
第一次写A*算法(这就是A*?如果这就是A*的话,那不就只是搜索的一个优化了= =,不过h函数如果弄难一点真的有些难设计) 其实就是判断t+h(x)(t为当前步数,h(x)为达到当前状态的最小步数) ...
随机推荐
- 第一章 JavaScript简介
DOM级别 DOM1:映射文档的结构 DOM2: DOM视图,定义了跟踪不同文档视图的接口(例如CSS应用前后的文档) DOM事件,定义了事件和事件处理的接口 DOM样式,定义了基于CSS为元素应用样 ...
- slf4j与logback的结合使用
参考:http://my.oschina.net/ydsakyclguozi/blog/412240 一.logback的介绍 Logback是由log4j创始人设计的又一个开源日志组件.logbac ...
- CodeForces Round #527 (Div3) D1. Great Vova Wall (Version 1)
http://codeforces.com/contest/1092/problem/D1 Vova's family is building the Great Vova Wall (named b ...
- PHP 在windows下配置sendmail,通过 mail() 函数发送邮件
php mail()函数在windows不能用,需要安装sendmail. 1. 从http://glob.com.au下载sendmail.zip 2. 解压sendmail.zip到目录下(最好使 ...
- C# 模拟串口发送接收
一.准备虚拟串口驱动工具 创建俩个虚拟串口,如图: 二.创建两个控制台程序 模拟串口的发送接收数据 1. 接收数据,代码如下: //遍历串行端口名称数组 foreach (string port in ...
- 洛谷 P2015 二叉苹果树
老规矩,先放题面 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端 ...
- C++解析(15):二阶构造模式
0.目录 1.构造函数与半成品对象 2.二阶构造 3.小结 1.构造函数与半成品对象 关于构造函数: 类的构造函数用于对象的初始化 构造函数与类同名并且没有返回值 构造函数在对象定义时自动被调用 问题 ...
- 洛谷 P1987 摇钱树
题目戳 题目描述 Cpg 正在游览一个梦中之城,在这个城市中有n棵摇钱树...这下,可让Cpg看傻了...可是Cpg只能在这个城市中呆K天,但是现在摇钱树已经成熟了,每天每棵都会掉下不同的金币(不属于 ...
- macvtap介绍
macvtap介绍 传统的linux网络虚拟化技术采用的是tap+bridge方式,将虚拟机连接到虚拟的tap网卡,然后将tap网卡加入到bridge.bridge相当于用软件实现的交换机,这种解决方 ...
- 【刷题】BZOJ 2599 [IOI2011]Race
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...