题面很邪恶啊。。。

一对新人请n-1对夫妻吃饭,人们坐在一张桌子的两侧,每一对互为夫妻关系的人必须坐在桌子的两侧。而且有些人两两之间会存在“通奸”关系,通奸关系不仅在男女之间,同性之间也有。新娘对面不可以座有通奸关系的人。判断是否存在可行的排座方案,存在的话输出和新娘同一排的人。

因为新娘对面不可以做有通奸关系的人,也就是说2sat求出的一组可行解是新娘对面的。

如果u和v有通奸关系,就连边u->v',v->u'。

有一点需要注意,就是要连一条边0->1

这样如果选了0就必须选1,那么就矛盾了,所以0一定不被选,选出来的就是新郎那一边的。很巧妙啊!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int N = ;
const int M = ; struct Edge {
int from, to, next;
} edge[M], edge2[M];
int head[N];
int cntE, cntE2;
void addedge(int u, int v) {
edge[cntE].from = u; edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;
}
void addedge2(int u, int v) {
edge2[cntE2].from = u; edge2[cntE2].to = v; edge2[cntE2].next = head[u]; head[u] = cntE2++;
} int dfn[N], low[N], idx;
int stk[N], top;
int in[N];
int kind[N], cnt; void tarjan(int u)
{
dfn[u] = low[u] = ++idx;
in[u] = true;
stk[++top] = u;
for (int i = head[u]; i != -; i = edge[i].next) {
int v = edge[i].to;
if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
else if (in[v]) low[u] = min(low[u], dfn[v]);
}
if (low[u] == dfn[u]) {
++cnt;
while () {
int v = stk[top--]; kind[v] = cnt; in[v] = false;
if (v == u) break;
}
}
} int opp[N], ind[N], col[N]; // 相对的点 入度 染色 col[]=1选择 bool topsort(int n) // 序号从0开始
{
for (int i = ; i < *n; i += ) {
int k1 = kind[i]; int k2 = kind[i^]; // 相对的两个的关系
//printf("%d %d %d %d\n", i, i^1, k1, k2);
if (k1 == k2) return false;
opp[k1] = k2; opp[k2] = k1;
}
memset(head, -, sizeof head);
int u, v;
for (int i = ; i < cntE; ++i) {
u = edge[i].from, v = edge[i].to;
if (kind[u] != kind[v]) { // 反向建图
addedge2(kind[v], kind[u]);
ind[kind[u]]++;
}
}
queue<int> q;
for (int i = ; i <= cnt; ++i) if (!ind[i]) q.push(i);
while (q.size()) {
u = q.front(); q.pop();
if (!col[u]) col[u] = , col[ opp[u] ] = -;
for (int i = head[u]; i != -; i = edge2[i].next)
if (--ind[edge2[i].to] == ) q.push(edge2[i].to);
}
return true;
} void init() {
cntE = cntE2 = ;
memset(head, -, sizeof head);
memset(dfn, , sizeof dfn);
memset(in, false, sizeof in);
idx = top = cnt = ;
memset(ind, , sizeof ind);
memset(col, , sizeof col);
} int main() {
int n, m;
int u, v;
while (scanf("%d%d", &n, &m) == ) {
if (n == && m == )break;
init();
while (m--) {
//3h 7h
char s1, s2;
scanf("%d%c%d%c", &u, &s1, &v, &s2);
u = s1=='w' ? u* : u*+;
v = s2=='w' ? v* : v*+;
if (!u || !v) continue;
addedge(u, v^);
addedge(v, u^);
}
addedge(, );
for (int i = ; i < * n; ++i) {
if (!dfn[i]) tarjan(i);
}
if (topsort(n)) {
for (int i = ; i < n; i++) {
if (col[ kind[*i] ] == ) printf("%dh", i);
else printf("%dw", i);
if (i < n - ) printf(" ");
else printf("\n");
}
} else printf("bad luck\n");
}
return ;
}

POJ 3648-Wedding(2-SAT)的更多相关文章

  1. POJ 3648 Wedding(2-SAT的模型运用+DFS | Tarjan)

    Wedding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10427   Accepted: 3170   Specia ...

  2. POJ 3279 Fliptile(翻格子)

    POJ 3279 Fliptile(翻格子) Time Limit: 2000MS    Memory Limit: 65536K Description - 题目描述 Farmer John kno ...

  3. POJ - 3308 Paratroopers(最大流)

    1.这道题学了个单词,product 还有 乘积 的意思.. 题意就是在一个 m*n的矩阵中,放入L个敌军的伞兵,而我军要在伞兵落地的瞬间将其消灭.现在我军用一种激光枪组建一个防御系统,这种枪可以安装 ...

  4. POJ 1274 The Perfect Stall || POJ 1469 COURSES(zoj 1140)二分图匹配

    两题二分图匹配的题: 1.一个农民有n头牛和m个畜栏,对于每个畜栏,每头牛有不同喜好,有的想去,有的不想,对于给定的喜好表,你需要求出最大可以满足多少头牛的需求. 2.给你学生数和课程数,以及学生上的 ...

  5. 学习笔记(two sat)

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

  6. POJ 3259 Wormholes (Bellman_ford算法)

    题目链接:http://poj.org/problem?id=3259 Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submis ...

  7. POJ 1006 Biorhythms (中国剩余定理)

    在POJ上有译文(原文右上角),选择语言:简体中文 求解同余方程组:x=ai(mod mi) i=1~r, m1,m2,...,mr互质利用中国剩余定理令M=m1*m2*...*mr,Mi=M/mi因 ...

  8. poj 1364 King(差分约束)

    题意(真坑):傻国王只会求和,以及比较大小.阴谋家们想推翻他,于是想坑他,上交了一串长度为n的序列a[1],a[2]...a[n],国王作出m条形如(a[si]+a[si+1]+...+a[si+ni ...

  9. poj 1201 Intervals(差分约束)

    做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~ 题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,500 ...

  10. POJ 水题(刷题)进阶

    转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6642573 部分解题报告添加新内容,除了原有的"大致题意&q ...

随机推荐

  1. 其实,前面倒腾那么多,只是为了想玩SPRING BOOT

    嘿嘿,,曲线达到.. 看来看来很多国内的速成,都不爽. 官方教程最体贴~~~:) http://docs.spring.io/spring-boot/docs/current/reference/ht ...

  2. php关于private、public成员变量访问问题

    如果类里面定义了__get($name)方法,则不论类的private成员还是public成员,都能够在类的外面通过类似$class->name访问到.如果是public变量,则不会自动调用ge ...

  3. MySQL在windows和linux下的表名大小写问题

    MySQL在windows下是不区分大小写的,将script文件导入MySQL后表名也会自动转化为小写,结果再想要将数据库导出放到linux服务 器中使用时就出错了.因为在linux下表名区分大小写而 ...

  4. struts2+jquery+ajax实现上传&&校验实例

    一直以为ajax不能做上传,直到最近看了一些文章.需要引入AjaxFileUploaderV2.1.zip,下载链接:http://pan.baidu.com/s/1i3L7I2T 代码和相关配置如下 ...

  5. HDU1312——Red and Black(DFS)

    Red and Black Problem DescriptionThere is a rectangular room, covered with square tiles. Each tile i ...

  6. Android 获取TextView 显示的字符串宽度

    工作上有业务需要判断textview是否换行,我的做法是判断textview要显示的字符串的宽度是否超过我设定的宽度,若超过则会执行换行. 项目中的其他地方也有这样的需求,故直接使用了那一块的代码.如 ...

  7. Android 通过广播启动另一个应用的Activity

    需求:现在有应用A和应用B,我需要在A应用中启动B应用中的某个Activity 实现:A应用中的Activity发送广播,关键代码如下: String broadcastIntent = " ...

  8. Django用户认证系统(二)Web请求中的认证

    在每个Web请求中都提供一个 request.user 属性来表示当前用户.如果当前用户未登录,则该属性为AnonymousUser的一个实例,反之,则是一个User实例. 你可以通过is_authe ...

  9. Function 1 - hello world

    Function 1 - hello world Make a simple function called greet that returns the most-famous "hell ...

  10. python项目

    python实战项目: http://www.the5fire.com/category/python实战/ python基础教程中的十个项目: python项目练习一:即时标记 python项目练习 ...