http://cogs.pro:8080/cogs/problem/problem.php?pid=pyzQimjkj

题意:有n个集合,每个集合有俩元素,要从n个中各选一个放一堆,但是有的俩不能同时取,让你找出一种选取方案。

思路:2-SAT板子,主要学一下这个算法。算法流程:

构图:若a,b不能同时选,连a->b'和b->a'

求图的极大强连通子图:直接tarjan。

缩点然后变成个新的DAG:因为一个强连通分量里选一个其他都要选,一个不选其他都不能选,所以直接缩成一个点。

对新图拓排:要存反边,这个一开始不造为啥,后来看解释是因为传递的是不选择标记,这边往前代走,对面那边往后代走(对这个起作用)。。选一个他后代都得选,不选谁谁的前代都不能选,so...

自底向上进行选择,删除。

输出。

#include<bits/stdc++.h>
#define oth(x) x&1?x+1:x-1
using namespace std;
const int N = 20010; struct Edge{
int to,nxt;
}e[50010];
int head[N],dfn[N],low[N],st[N],bel[N];
bool vis[N];
int ru[N],q[N],opp[N],pr[N];
int tot_edge,n,nn,m,tot_node,top,cnt_block,L,R;
vector<int>mp[N]; inline int read() {
int x = 0,f = 1;char ch = getchar();
for (; ch<'0'||ch>'9'; ch=getchar()) if(ch=='-') f=-1;
for (; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
return x * f;
}
void add_edge(int u,int v){
e[++tot_edge].to = v;
e[tot_edge].nxt = head[u];
head[u] = tot_edge;
}
void tarjan(int u){
dfn[u] = low[u] = ++tot_node;
st[++top] = u;
vis[u] = true;
for(int i=head[u];i;i=e[i].nxt){
int v = e[i].to;
if(!dfn[v]){
tarjan(v);
low[u] = min(low[v],low[u]);
}
else if(vis[v])
low[u] = min(dfn[v],low[u]);
}
if(low[u]==dfn[u]){
++cnt_block;
do{
vis[st[top]] = false;
bel[st[top]] = cnt_block;
top--;
}while(st[top+1]!=u);
}
}
void topsort(){
L=1;R=0;
for(int i=1;i<=cnt_block;i++){
if(ru[i]==0) q[++R] = i;
}
while(L<=R){
int u = q[L++];
if(pr[u]) continue;
pr[u] = 1;pr[opp[u]] = 2;
int sz = mp[u].size();
for(int i=0;i<sz;i++){
int v = mp[u][i];
ru[v]--;
if(ru[v]==0) q[++R] = v;
}
}
}
bool work(){
for(int i=1;i<=nn;i++){
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=nn;i++){
if(bel[i]==bel[oth(i)]) return false;
opp[bel[i]] = bel[oth(i)];
opp[bel[oth(i)]] = bel[i];
}
for(int u=1;u<=nn;u++){
for(int i=head[u];i;i=e[i].nxt){
int v = e[i].to;
if(bel[u]!=bel[v]){
ru[bel[u]]++;
mp[bel[v]].push_back(bel[u]);
}
}
}
topsort();
return true;
}
int main(){
freopen("spo.in","r",stdin);
freopen("spo.out","w",stdout);
n = read(),m = read(),nn = n<<1;
for(int i=1;i<=m;i++){
int a = read(),b = read();
add_edge(a,oth(b));
add_edge(b,oth(a));
}
if(work()){
for(int i=1;i<=nn;i++){
if(pr[bel[i]]==1) cout<<i<<endl;
}
}
else puts("NIE");
return 0;
}

cogs 313. [POI2001] 和平委员会(2-SAT的更多相关文章

  1. COGS:313. [POI2001] 和平委员会

    313. [POI2001] 和平委员会 ★★☆   输入文件:spo.in   输出文件:spo.out   评测插件时间限制:1 s   内存限制:128 MB 题目描述 根据宪法,Bytelan ...

  2. [POI2001]和平委员会

    题目描述 根据宪法,Byteland民主共和国的公众和平委员会应该在国会中通过立法程序来创立. 不幸的是,由于某些党派代表之间的不和睦而使得这件事存在障碍. 此委员会必须满足下列条件: 每个党派都在委 ...

  3. 【POI2001】【HDU1814】和平委员会

    题面 Description 根据宪法,Byteland民主共和国的公众和平委员会应该在国会中通过立法程序来创立. 不幸的是,由于某些党派代表之间的不和睦而使得这件事存在障碍. 此委员会必须满足下列条 ...

  4. [模板]2-SAT 问题&和平委员会

    tarjan的运用 this is a problem:link 2-SAT处理的是什么 首先,把「2」和「SAT」拆开.SAT 是 Satisfiability 的缩写,意为可满足性.即一串布尔变量 ...

  5. HDU1814和平委员会

    题目大意: 有n对的人,编号从1-2*n,m对的人之间互相不喜欢,每对人中必徐选1个人加入和平委员会,求字典序最小的解 -------------------------------- 2-SAT问题 ...

  6. HDU 1814 Peaceful Commission / HIT 1917 Peaceful Commission /CJOJ 1288 和平委员会(2-sat模板题)

    HDU 1814 Peaceful Commission / HIT 1917 Peaceful Commission /CJOJ 1288 和平委员会(2-sat模板题) Description T ...

  7. LOJ10097和平委员会

    POI 2001 根据宪法,Byteland民主共和国的公众和平委员会应该在国会中通过立法程序来创立. 不幸的是,由于某些党派代表之间的不和睦而使得这件事存在障碍. 此委员会必须满足下列条件: 每个党 ...

  8. P5782-[POI2001]和平委员会【2-SAT】

    正题 题目链接:https://www.luogu.com.cn/problem/P5782 题目大意 \(n\)对人,每对之间恰好有一个人出席.\(m\)对仇恨关系表示两个人不能同时出席. 求是否有 ...

  9. 2-sat问题学习记录

    如果你不知道什么是sat问题,请看以下问答. Q:sat问题是什麽?A:首先你有n个布尔变量,然后你有一个关于这n个布尔变量的布尔表达式,问你,如果让你随意给这n个布尔变量赋值,这个布尔表达式能否成立 ...

随机推荐

  1. JS-对象中写方法

  2. Linux 常见的常识及常用快捷键方式

    1.  ,请写出linux系统中常见一级目录的名称及作用. /root :   超级用户的家目录 /home:  普通用户的家目录 /boot:   启动目录,启动相关文件(系统内核启动文件) /de ...

  3. X-Admin&ABP框架开发-系统日志

    网站正常运行中有时出现异常在所难免,查看系统运行日志分析问题并能够根据错误信息快速解决问题尤为重要,ABP对于系统运行日志这块已经做了很好的处理,默认采用的Log4Net已经足够满足开发过程中的需要了 ...

  4. Tomcat发布War包或者Maven项目

    在tomcat的conf目录下面的server.xml中修改如下: Host name="localhost"  appBase="webapps" unpac ...

  5. Linux系统下减少LV(逻辑卷)容量

    查看文件系统现有 lv_test 容量,总计9.9G,已使用2% 命令 df -h 2 查看系统中的 PV 情况 命令:pvdisplay vg_test 下有两个 PV,分别为  /dev/sdb1 ...

  6. 有容云-PPT | 当微服务遇见容器

    编者注: 本文为10月29日有容云高级技术顾问龙淼在Docker Live时代线下系列-广州站中演讲的PPT,本次线下沙龙为有容云倾力打造Docker Live时代系列主题线下沙龙,每月一期畅聊容器技 ...

  7. Linux打开网易云的问题

    网易云需要ROOT权限启动,期间终端不能关闭退出,否则网易云音乐会自动退出.    终端输入:sudo netease-cloud-music &u

  8. 算法与数据结构基础 - 回溯(Backtracking)

    回溯基础 先看一个使用回溯方法求集合子集的例子(78. Subsets),以下代码基本说明了回溯使用的基本框架: //78. Subsets class Solution { private: voi ...

  9. 洛谷 P3413 SAC#1 - 萌数

    题意简述 求l~r之间存在长度至少为2的回文子串的正整数的个数 题解思路 数位DP 注意到有偶数长度的回文串必有长度为2的回文串,有奇数长度的回文串必有长度为3的回文串 所以只需判断与前一位,前两位是 ...

  10. 【openmp】for循环的break问题

    问题描述:在用openmp并行化处理for循环的时候,便无法在for循环中用break语句,那么我们如何实现这样的机制呢?在stackoverflow上看到一个不错的回答总结一下. volatile ...