题意:

      一对夫妻结婚,请来了n对夫妻,所有人坐在同一张桌子上吃饭,这张桌子是长方形的可以坐两排人,有如下限制

(1) 新娘和新郎不做同一侧。

(2) 每对来的夫妻也不能坐在同一侧。 

(3) 有一些人有暧昧关系(男女,男男,或者女女),有暧昧关系的两

个人不可以同时坐在新娘对面。


输出一组可行解,输出的是坐在新娘对面的人。

思路:

     根据限制关系,而且还是二选一,显然这个是2sat,对于每个人,都拆成两个点,一个是a表示坐在新娘这一侧,另一个是~a表示坐在新郎这一侧,则对于任何有暧昧关系的,要么一边坐一个,要不同时坐在新娘这一侧,则只要他们两个中至少有一个1就行了,建图是这样 ~a -> b ,~b -> a,对于每一对,他们不能坐在同一侧则不能相同,建图是 a -> ~b ,b -> ~a ,~a ->b ,~b ->
a ,还有就是新娘必须坐在新娘这侧,直接 ~a -> a.


#include<stdio.h>
#include<string.h>
#include<stack> #define N_node 5000
#define N_edge 100000
#define R 1
#define B 2 using namespace std; typedef struct
{
int to ,next;
}STAR; STAR E1[N_edge] ,E2[N_edge];
int list1[N_node] ,list2[N_node] ,tot;
int Belong[N_node] ,cnt;
int mark[N_node] ,Col[N_node];
stack<int>st ,stt; void add(int a ,int b)
{
E1[++tot].to = b;
E1[tot].next = list1[a];
list1[a] = tot; E2[tot].to = a;
E2[tot].next = list2[b];
list2[b] = tot;
} void DFS1(int s)
{
mark[s] = 1;
for(int k = list1[s] ;k ;k = E1[k].next)
if(!mark[E1[k].to]) DFS1(E1[k].to);
st.push(s) ,stt.push(s);
} void DFS2(int s)
{
mark[s] = 1;
Belong[s] = cnt;
for(int k = list2[s] ;k ;k = E2[k].next)
if(!mark[E2[k].to]) DFS2(E2[k].to);
} bool solve(int n)
{
memset(mark ,0 ,sizeof(mark));
while(!st.empty()) st.pop();
while(!stt.empty()) stt.pop();
for(int i = 0 ;i < 4 * n ;i ++)
if(!mark[i]) DFS1(i);
memset(mark ,0 ,sizeof(mark)) ,cnt = 0;
while(!st.empty())
{
int xin = st.top();
st.pop();
if(mark[xin]) continue;
cnt ++;
DFS2(xin);
}
for(int i = 0 ;i < n * 4 ;i += 2)
if(Belong[i] == Belong[i^1]) return 0;
return 1;
} int main ()
{
int i ,n ,m ,a ,b;
char c1 ,c2;
while(~scanf("%d %d" ,&n ,&m) && n + m)
{
memset(list1 ,0 ,sizeof(list1));
memset(list2 ,0 ,sizeof(list2)) ,tot = 1;
for(i = 1 ;i <= m ;i ++)
{
scanf("%d%c%d%c" ,&a ,&c1 ,&b ,&c2);
a = a * 2 + (c1 == 'h' ? 1 : 0);
b = b * 2 + (c2 == 'h' ? 1 : 0);
add(a * 2 + 1 ,b * 2);
add(b * 2 + 1 ,a * 2);
}
for(i = 0 ;i < n ;i ++)
{
a = i * 2 ,b = i * 2 + 1;
add(a * 2 + 1 ,b * 2) ,add(b * 2 + 1 ,a * 2);
add(a * 2 ,b * 2 + 1) ,add(b * 2 ,a * 2 + 1);
}
add(1 ,0);
if(!solve(n))
{
printf("bad luck\n");
continue;
}
memset(Col ,0 ,sizeof(Col));
while(!stt.empty())
{
i = stt.top() ,stt.pop();
if(Col[i]) continue;
Col[i] = B ,Col[i^1] = R;
}
int mk = 0;
for(i = 4 ;i < n * 4 ;i += 2)
{
if(Col[i] == B) continue;
if(mk) printf(" ");mk = 1;
printf("%d" ,i / 4);
i % 4 > 1 ? printf("h") : printf("w");
}
puts("");
}
return 0;
}

poj3648 2-sat的更多相关文章

  1. 多边形碰撞 -- SAT方法

    检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...

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

  3. poj3648

    poj3648 题意 有一对新人结婚,n-1对夫妇去参加婚礼.有一个很长的座子,新娘与新郎坐在座子的两边(相反).接下来n-1对夫妇就坐,其中任何一对夫妇都不能坐在同一边,且(有一些人有奸情)这些有奸 ...

  4. Map Labeler POJ - 2296(2 - sat 具体关系建边)

    题意: 给出n个点  让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...

  5. 学习笔记(two sat)

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

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

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

  7. HIT 1917 2—SAT

    题目大意:一国有n个党派,每个党派在议会中都有2个代表, 现要组建和平委员会,要从每个党派在议会的代表中选出1人,一共n人组成和平委员会. 已知有一些代表之间存在仇恨,也就是说他们不能同时被选为和平委 ...

  8. 2 - sat 模板(自用)

    2-sat一个变量两种状态符合条件的状态建边找强连通,两两成立1 - n 为第一状态(n + 1) - (n + n) 为第二状态 例题模板 链接一  POJ 3207 Ikki's Story IV ...

  9. SAT考试里最难的数学题? · 三只猫的温暖

    问题 今天无意中在Quora上看到有人贴出来一道号称是SAT里最难的一道数学题,一下子勾起了我的兴趣.于是拿起笔来写写画画,花了差不多十五分钟搞定.觉得有点意思,决定把解题过程记下来.原帖的图太小,我 ...

  10. 世界碰撞算法原理和总结(sat gjk)

    序言 此文出于作者的想法,从各处文章和论文中,总结和设计项目中碰撞结构处理方法.如有其它见解,可以跟作者商讨.(杨子剑,zijian_yang@yeah.net). 在一个世界中,有多个物体,物体可以 ...

随机推荐

  1. 微信小程序左滑删除

    <view class="touch-item {{item.isTouchMove ? 'touch-move-active' : ''}}" data-index=&qu ...

  2. 蓝桥杯-分考场(dfs)

    分考场 PREV-53 这题的解决方法使用dfs,因为数据很小,才100. 每次当前的人人是否可以和前面的组队,设置两个数组group和fri /*DFS求解:思路每次判断输入的人是否可以和前面的组队 ...

  3. Github Fork与远程主分支同步

    fork与主分支同步(5步) 1. git remote add upstream git@github.com:haichong98/gistandard.git   新建一个upstream的远程 ...

  4. python3 获取博彩网站页面下所有域名(批量)

    已有的域名信息 详细实现过程如下 #!/usr/bin/env python # -*- coding:utf-8 -*- import requests from bs4 import Beauti ...

  5. CSS垂直布局

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  6. 对控制器类型“StudentController”的操作“Edit”的当前请求在下列操作方法之间不明确:

    "/"应用程序中的服务器错误. 对控制器类型"StudentController"的操作"Edit"的当前请求在下列操作方法之间不明确:类型 ...

  7. 汇编 JCC指令表

    JCC指令 中文含义 英文原意 检查符号位 典型c应用 JZ/JE 若为0则跳转:若相等则跳转 jump if zero;jump if equal ZF=1 if (i == j);if (i == ...

  8. 干掉前端!3分钟纯 Java 注解搭个管理系统

    大家好,我是小富~ 最近接触到个新项目,发现它用了一个比较有意思的框架,可以说实现了我刚入行时候的梦想,所以这里马不停蹄的和大家分享下. 在我刚开始工作接触的项目都还没做前后端分离,经常需要后端来维护 ...

  9. Java学习之路 -- Java怎么学?

    @ 目录 java基础怎么学? 学完基础学什么? 几个常用框架学完学什么? MQ JVM的知识跑不掉 微服务等等 其他 数据结构和算法 java基础怎么学? 当时,作为懵懂的小白,大一学习了c和c++ ...

  10. 推荐一款全能测试开发神器:Mockoon!1分钟快速上手!

    1. 说一下背景 在日常开发或者测试工作中,经常会因为下游服务不可用或者不稳定时,通过工具或者技术手段去模拟一个HTTP Server,或者模拟所需要的接口数据. 这个时候,很多人脑海里,都会想到可以 ...