Wedding(2-SAT)
稍微复杂一点的2-SAT。
读题之后发现有以下限制:
1.每一对夫妻(包括新郎和新娘)不能坐在桌子的一侧。
2.对于一些给定的非法(自行脑补)的关系,这两个人不能坐在新娘的同一侧。
因为每个人只有两种就坐方式,所以每个人可以被看成一个布尔变量。我们把每一对夫妻拆成两个点,分别表示是否坐在新郎的一侧。这样只要夫妻直接不连边,就不会坐在一起,然后把非法关系的两个人,每个人向对方的否定去连边,因为如果一个人坐在一边,另一个人不可以坐在这边,那么他的否定必然要坐在这边。
注意新娘的对面是必须有新郎的。把新娘向新郎连一条边,这样相当于是自己向自己的否定连边,那么结果为假,也就是新郎坐在了新郎那一侧。这样之后我们跑2-SAT即可。
不过注意一下,因为我们设定的是是否坐在新郎的一侧,我们要求的是是否坐在新娘的一侧,所以最后在判断的时候判断的条件要反过来。
看一下代码。(感觉此题有点奇怪难懂?)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = ;
const int INF = ; int read()
{
int ans = ,op = ;
char ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-') op = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
ans *= ;
ans += ch - '';
ch = getchar();
}
return ans * op;
} struct edge
{
int next,from,to;
}e[M<<]; int n,m,head[M],cnt,scc[M],dfn[M],low[M],idx,ecnt,a,b,stack[M],top;
char c,d;
bool vis[M],flag; int rev(int x)
{
return x > n ? x - n : x + n;
} void clear()
{
memset(e,,sizeof(e));
memset(head,,sizeof(head));
memset(scc,,sizeof(scc));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
ecnt = cnt = idx = ;
} void add(int x,int y)
{
e[++ecnt].to = y;
e[ecnt].from = x;
e[ecnt].next = head[x];
head[x] = ecnt;
} void build()
{
rep(i,,m)
{
scanf("%d%c %d%c",&a,&c,&b,&d);
a++,b++;
if(c == 'h') a += n;
if(d == 'h') b += n;
add(a,rev(b)),add(b,rev(a));
}
add(,+n);
} void tarjan(int x)
{
dfn[x] = low[x] = ++idx;
stack[++top] = x,vis[x] = ;
for(int i = head[x];i;i = e[i].next)
{
if(!dfn[e[i].to]) tarjan(e[i].to),low[x] = min(low[x],low[e[i].to]);
else if(vis[e[i].to]) low[x] = min(low[x],dfn[e[i].to]);
}
if(low[x] == dfn[x])
{
int p;
cnt++;
while(p = stack[top--])
{
scc[p] = cnt,vis[p] = ;
if(p == x) break;
}
}
} int main()
{
while()
{
n = read(),m = read();
if(!n && !m) break;
clear(),build();
rep(i,,n<<) if(!dfn[i]) tarjan(i);
flag = ;
rep(i,,n)
{
if(scc[i] == scc[i+n])
{
flag = ;
break;
}
}
if(!flag) printf("bad luck\n");
else
{
rep(i,,n)
{
if(scc[i] > scc[i+n]) printf("%d%c ",i-,'w');
else printf("%d%c ",i-,'h');
}
enter;
}
}
return ;
}
Wedding(2-SAT)的更多相关文章
- POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang
Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...
- 学习笔记(two sat)
关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...
- Katu Puzzle POJ - 3678 (2 - sat)
有N个变量X1X1~XNXN,每个变量的可能取值为0或1. 给定M个算式,每个算式形如 XaopXb=cXaopXb=c,其中 a,b 是变量编号,c 是数字0或1,op 是 and,or,xor 三 ...
- LA 3211 飞机调度(2—SAT)
https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...
- UVA 11294 Wedding(2-sat)
2-sat.不错的一道题,学到了不少. 需要注意这么几点: 1.题目中描述的是有n对夫妇,其中(n-1)对是来为余下的一对办婚礼的,所以新娘只有一位. 2.2-sat问题是根据必然性建边,比如说A与B ...
- 转载:hdu 题目分类 (侵删)
转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...
- spring定时任务详解(@Scheduled注解)( 转 李秀才的博客 )
在springMVC里使用spring的定时任务非常的简单,如下: (一)在xml里加入task的命名空间 xmlns:task="http://www.springframework.or ...
- MongoDB 聚合管道(Aggregation Pipeline)
管道概念 POSIX多线程的使用方式中, 有一种很重要的方式-----流水线(亦称为"管道")方式,"数据元素"流串行地被一组线程按顺序执行.它的使用架构可参考 ...
- mysql触发器,答题记录表同步教学跟踪(用户列表)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABVQAAAOOCAIAAABgEw4AAAAgAElEQVR4nOy92VcT27r/zX+xLtflvt
- Linux版Matlab R2015b的bug——脚本运行的陷阱(未解决)
0 系统+软件版本 系统:CentOS 6.7 x64, 内核 2.6.32-573.el6.x86_64软件:Matlab R2015b(包括威锋网和东北大学ipv6下载的资源,都测试过) 1 脚本 ...
随机推荐
- mysql常用命令用法
Mysql帮助文档地址:http://dev.mysql.com/doc/ 1.创建数据库: create database database_name; 2.选择数据库: use database_ ...
- YOLOv3配置(win10+opencv3.40+cuda9.1+cudnn7.1+vs2015)
最近心血来潮想学一下YOLOv3,于是就去网上看了YOLOv3在win10下的配置教程.在配置过程中塌坑无数,花了很多时间和精力,所以我想就此写一篇博客来介绍在在win10+vs2015的环境下如何配 ...
- 90-Standard Deviation 标准离差指标.(2015.7.4)
Standard Deviation 标准离差指标 ~计算: StdDev = SQRT (SUM (CLOSE - SMA (CLOSE, N), N)^2)/N 注解: SQRT - 正方体根: ...
- 2018/08/23 cstring中memset()函数的运用
好多东西其实以前已经查过了,然后当时理解的还行,可是过段时间没用有些又会忘记,然后又去找资料又查,浪费了不少的时间和精力,所以,我,曾国强,今天起,要好好做笔记了! 今天复习第一个知识点,为什么要叫复 ...
- UVa 548 树(已知其中两种遍历, 还原树)
题意: 给出后序遍历和先序遍历, 还原一棵树, 然后求出从根节点到叶子的最小路劲和. 分析: 已知后序遍历, 那么后序的最后一个节点就是根节点, 然后在中序中找到这个节点, 它的左边就是左子树, 它的 ...
- 图论算法——最短路径Dijkstra,Floyd,Bellman Ford
算法名称 适用范围 算法过程 Dijkstra 无负权 从s开始,选择尚未完成的点中,distance最小的点,对其所有边进行松弛:直到所有结点都已完成 Bellman-Ford 可用有负权 依次对所 ...
- 易接SDK ios9以上无法弹出充值界面的一种情况
充值需要用到http请求: 打开info.plist, 在app tansport security setting 这个项 , 加入 NSAllowsArbitraryLoads YES
- 使用JS对form的内容验证失败后阻止提交
1.form的两个事件 submit,提交表单,如果直接调用该函数,则直接提交表单 onSubmit,提交按钮点击时先触发,然后触发submit事件.如果不加控制的话,默认返回true,因此表单总能提 ...
- [luoguP1388] 算式(DP)
传送门 看这个n<=15本以为是个状压DP 还是too young 这个题最神奇的地方是加括号是根据贪心的策略. 发现只有在一连串的加号两边加上括号才是最优的(想一想,为什么?) f[i][j] ...
- [转]MySQL5字符集支持及编码研究
前言 在更新数据库时,有时会遇到这样的错误: Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (utf8_general_ci,COER ...