传送门

稍微复杂一点的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)的更多相关文章

  1. 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 ...

  2. 学习笔记(two sat)

    关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...

  3. Katu Puzzle POJ - 3678 (2 - sat)

    有N个变量X1X1~XNXN,每个变量的可能取值为0或1. 给定M个算式,每个算式形如 XaopXb=cXaopXb=c,其中 a,b 是变量编号,c 是数字0或1,op 是 and,or,xor 三 ...

  4. LA 3211 飞机调度(2—SAT)

    https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...

  5. UVA 11294 Wedding(2-sat)

    2-sat.不错的一道题,学到了不少. 需要注意这么几点: 1.题目中描述的是有n对夫妇,其中(n-1)对是来为余下的一对办婚礼的,所以新娘只有一位. 2.2-sat问题是根据必然性建边,比如说A与B ...

  6. 转载:hdu 题目分类 (侵删)

    转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...

  7. spring定时任务详解(@Scheduled注解)( 转 李秀才的博客 )

    在springMVC里使用spring的定时任务非常的简单,如下: (一)在xml里加入task的命名空间 xmlns:task="http://www.springframework.or ...

  8. MongoDB 聚合管道(Aggregation Pipeline)

    管道概念 POSIX多线程的使用方式中, 有一种很重要的方式-----流水线(亦称为"管道")方式,"数据元素"流串行地被一组线程按顺序执行.它的使用架构可参考 ...

  9. mysql触发器,答题记录表同步教学跟踪(用户列表)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABVQAAAOOCAIAAABgEw4AAAAgAElEQVR4nOy92VcT27r/zX+xLtflvt

  10. Linux版Matlab R2015b的bug——脚本运行的陷阱(未解决)

    0 系统+软件版本 系统:CentOS 6.7 x64, 内核 2.6.32-573.el6.x86_64软件:Matlab R2015b(包括威锋网和东北大学ipv6下载的资源,都测试过) 1 脚本 ...

随机推荐

  1. 输出一定范围unicode对应符号

    #本程序没有考虑对0x的处理,请勿输入,直接输入16进制位即可 begin = input("起始点:") end = input("结束点:") b_int0 ...

  2. java成员变量

      成员变量是在类范围内定义的变量   局部变量是在一个方法内定义的变量 https://www.cnblogs.com/zhengchenhui/p/5762966.html

  3. codeforces 88E Interesting Game

    题目大意: 两个好朋友再将一堆物品分堆,每次都将一堆物品分成数量连续的至少两个堆,直到一个人不能分堆为输 第一次做博弈问题,看了百度文库的http://wenku.baidu.com/link?url ...

  4. [NOIP2007] 提高组 洛谷P1099 树网的核

    题目描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并 ...

  5. JSTL-格式标签库

    主页:http://www.cnblogs.com/EasonJim/p/6958992.html的分支页. 一.<fmt:formatNumber> <fmt:formatNumb ...

  6. Linux纯Shell实现DNSPod动态域名

    http://www.anrip.com/post/872 开发背景: 公司有台嵌入式拨号上网设备,内置busybox和完整wget命令(支持https协议),但没有curl.python.ruby. ...

  7. ViewFlipper实现ViewPager的页面切换效果

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  8. 【转】实现一个自己的promise

    转, 原文:http://blog.csdn.net/yibingxiong1/article/details/68075416------------------------------------ ...

  9. Android 实现形态各异的双向側滑菜单 自己定义控件来袭

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39670935.本文出自:[张鸿洋的博客] 1.概述 关于自己定义控件側滑已经写了 ...

  10. [Maid] Write Tasks in Markdown with Maid

    Maid enables you to write your tasks in Markdown. Create a maidfile.md or a README.mdthen add Header ...