BZOJ3495 : PA2010 Riddle
2-SAT。
建立n个变量,其中第i个变量表示第i个城市是否是首都。
对于边(x,y),连边x->y',y->x'。
对于一个有y个城市的国家,新建2y个变量,分别表示前i个城市和后i个城市中是否有首都。
然后求出SCC,判断是否存在合法的方案即可,时间复杂度$O(n+m)$。
#include<cstdio>
const int N=1000010,M=6000010;
int n,m,k,i,x,y,tot,f[N][2],pre[N][2],suf[N][2],q[M],t,from[M];bool v[M];
struct E{int v;E*nxt;}*g[M],*h[M],pool[N*24],*cur=pool,*p;
inline void add(int x,int y){
p=cur++;p->v=y;p->nxt=g[x];g[x]=p;
p=cur++;p->v=x;p->nxt=h[y];h[y]=p;
}
void dfs1(int x){
v[x]=1;
for(E*p=g[x];p;p=p->nxt)if(!v[p->v])dfs1(p->v);
q[++t]=x;
}
void dfs2(int x,int y){
v[x]=0,from[x]=y;
for(E*p=h[x];p;p=p->nxt)if(v[p->v])dfs2(p->v,y);
}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int main(){
read(n),read(m),read(k);
for(i=1;i<=n;i++)f[i][0]=++tot,f[i][1]=++tot;
while(m--)read(x),read(y),add(f[x][0],f[y][1]),add(f[y][0],f[x][1]);
while(k--){
read(y);
for(i=1;i<=y;i++){
pre[i][0]=++tot,pre[i][1]=++tot;
suf[i][0]=++tot,suf[i][1]=++tot;
read(x);
add(f[x][1],pre[i][1]);
add(f[x][1],suf[i][1]);
add(pre[i][0],f[x][0]);
add(suf[i][0],f[x][0]);
}
for(i=2;i<=y;i++){
add(pre[i-1][1],pre[i][1]);
add(pre[i-1][1],suf[i][0]);
add(pre[i-1][0],suf[i][1]);
add(suf[i][1],suf[i-1][1]);
add(suf[i][1],pre[i-1][0]);
add(suf[i][0],pre[i-1][1]);
}
}
for(i=1;i<=tot;i++)if(!v[i])dfs1(i);
for(i=tot;i;i--)if(v[q[i]])dfs2(q[i],q[i]);
for(i=1;i<n;i+=2)if(from[i]==from[i+1])return puts("NIE"),0;
return puts("TAK"),0;
}
BZOJ3495 : PA2010 Riddle的更多相关文章
- BZOJ3495 PA2010 Riddle 【2-sat】
题目链接 BZOJ3495 题解 每个城市都有选和不选两种情况,很容易考虑到2-sat 边的限制就很好设置了,主要是每个郡只有一个首都的限制 我们不可能两两之间连边,这样复杂度就爆炸了 于是乎就有了一 ...
- 3495: PA2010 Riddle
3495: PA2010 Riddle 链接 分析: 每个点要么建首都,要么不建,并且一个点建了,会导致一些点不能建.所以可以考虑2-sat. 但是如果在每个郡里两两连边,边数是n^2的. 考虑用前缀 ...
- 3495: PA2010 Riddle 2-sat 前缀优化
3495: PA2010 Riddle 2-sat 前缀优化 链接 bzoj 思路 不想说啥了,看hwim的吧,我去睡觉了zZ. 代码 /******************************* ...
- 【BZOJ3495】PA2010 Riddle
题目大意 有\(n\)个城镇被分成了\(k\)个郡,有\(m\)条连接城镇的无向边.要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都. 题目分析 每条边至少有一个端点是首都,每个郡至多 ...
- 【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.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& ...
- 【BZOJ】3495: PA2010 Riddle 2-SAT算法
[题意]有n个城镇被分成了k个郡,有m条连接城镇的无向边.要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都.n,m,k<=10^6. [算法]2-SAT,前后缀优化建图 [题解] ...
随机推荐
- Stanford机器学习---第四讲. 神经网络的表示 Neural Networks representation
原文 http://blog.csdn.net/abcjennifer/article/details/7749309 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...
- CUDA 6.5 && VS2013 && Win7:创建CUDA项目
运行环境: Win7+VS2013+CUDA6.5 1.创建win32空项目 2.右键项目解决方案-->生成项目依赖项-->生成自定义 3.右键项目解决方案-->属性-->配置 ...
- virgo虚拟桌面
转载: http://www.appinn.com/virgo-virtual-desktop-for-windows/ virgo 是一款 Windows 下的极简虚拟桌面,源程序自身只有 7KB, ...
- ICA
参考:http://www.cnblogs.com/jerrylead/archive/2011/04/19/2021071.html 对高斯分布的样本点效果不好.数学真是博大精深啊
- Segment Tree Query I & II
Segment Tree Query I For an integer array (index from 0 to n-1, where n is the size of this array), ...
- Select Top在不同数据库中的使用
1. oracle数据库 SELECT * FROM TABLE1 WHERE ROWNUM<=N 2. Infomix数据库 SELECT FIRST N * FROM TABLE1 3. D ...
- 10.python之socket和socketserver
1.socket介绍 socket的英文原义是"孔"或"插座".作为BSD UNIX的进程通信机制,取后一种意思.通常也 称作"套接字",用 ...
- MST:Conscription(POJ 3723)
男女搭配,干活不累 题目大意:需要招募女兵和男兵,每一个人都的需要花费1W元的招募费用,但是如果有一些人之间有亲密的关系,那么就会减少一定的价钱,如果给出1~9999的人之间的亲密关系,现在要你求 ...
- 6个朋友(codevs 2832)
2832 6个朋友 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有这么一种说法:认识6个人,你就认识全世 ...
- SQL如何在数据库间复制表
方法一: DB1 tb1 DB2 tb2 选择DB1 到表的列表那里选择tb1表 右键 所有任务 数据导出 下一步 选择你要导出的数据库DB1 下一步 选择你要导入的数据库DB2 下一步 选 ...