poj 3648 Wedding 2-SAT问题入门题目

Description

Up to thirty couples will attend a wedding feast, at which they will be seated on either side of a long table. The bride and groom sit at one end, opposite each other, and the bride wears an elaborate headdress that keeps her from seeing people on the same side as her. It is considered bad luck to have a husband and wife seated on the same side of the table. Additionally, there are several pairs of people conducting adulterous relationships (both different-sex and same-sex relationships are possible), and it is bad luck for the bride to see both members of such a pair. Your job is to arrange people at the table so as to avoid any bad luck.

Input

The input consists of a number of test cases, followed by a line containing 0 0. Each test case gives n, the number of couples, followed by the number of adulterous pairs, followed by the pairs, in the form "4h 2w" (husband from couple 4, wife from couple 2), or "10w 4w", or "3h 1h". Couples are numbered from 0 to n - 1 with the bride and groom being 0w and 0h.

Output

For each case, output a single line containing a list of the people that should be seated on the same side as the bride. If there are several solutions, any one will do. If there is no solution, output a line containing "bad luck".

Sample Input

10 6
3h 7h
5w 3w
7h 6w
8w 3w
7h 3w
2w 5h
0 0

Sample Output

1h 2h 3w 4h 5h 6h 7h 8h 9h

这题题目题意简直可怕有一对新人结婚,邀请n对夫妇去参加婚礼。有一张很长的桌子,人只能坐在桌子的两边,还要满足下面的要求:1.每对夫妇不能坐在同一侧 2.n对夫妇之中可能有通奸关系(包括男男,男女,女女),有通奸关系的不能同时坐在新娘的对面,可以分开坐,可以同时坐在新娘这一侧。如果存在一种可行的方案,输出与新娘同侧的人。

源地址 https://blog.csdn.net/u012915516/article/details/48442265

SAT这种问题 和网络流一样 只要图建对了 就对了 主要是建图问题   

特殊情况:当新郞有奸情的时候,与他有奸情的必需选择了(新浪在对面),

当新娘有奸情时候没关系,不处理。



 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 #include <string>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <stack>
 9
10 using namespace std;
11 const int maxn = 1e5 + 10;
12 const int  mod = 1e9 + 7 ;
13 const int INF = 0x7ffffff;
14 struct node {
15     int v, next;
16 } edge[maxn];
17 int head[maxn], dfn[maxn], low[maxn];
18 int s[maxn], belong[maxn], instack[maxn];
19 int tot, cnt, top, flag, n, m;
20 void init() {
21     tot = cnt = top = flag = 0;
22     memset(s, 0, sizeof(s));
23     memset(head, -1, sizeof(head));
24     memset(dfn, 0, sizeof(dfn));
25     memset(instack, 0, sizeof(instack));
26 }
27 void add(int u, int v ) {
28     edge[tot].v = v;
29     edge[tot].next = head[u];
30     head[u] = tot++;
31 }
32 void tarjan(int v) {
33     dfn[v] = low[v] = ++flag;
34     instack[v] = 1;
35     s[top++] = v;
36     for (int i = head[v] ; ~i ; i = edge[i].next ) {
37         int j = edge[i].v;
38         if (!dfn[j]) {
39             tarjan(j);
40             low[v] = min(low[v], low[j]);
41         } else if (instack[j]) low[v] = min(low[v], dfn[j]);
42     }
43     if (dfn[v] == low[v]) {
44         cnt++;
45         int t;
46         do {
47             t = s[--top];
48             instack[t] = 0;
49             belong[t] = cnt;
50         } while(t != v) ;
51     }
52 }
53 int ans[maxn];
54 int check() {
55     for (int i = 0 ; i < 2 * n ; i++)
56         if (!dfn[i]) tarjan(i);
57     for (int i = 0 ; i < 2 * n ; i += 2) {
58         if (belong[i] == belong[i + 1]) return 0;
59         if (belong[i] < belong[i + 1]) ans[i / 2] = i;
60         else ans[i / 2] = i + 1;
61     }
62     return 1;
63 }
64 int main() {
65     while(scanf("%d%d", &n, &m) != EOF) {
66         if (n == 0 && m == 0) break;
67         int t1, t2;
68         char c1, c2;
69         init();
70         memset(ans, 0, sizeof(ans));
71         for (int i = 0 ; i < m ; i++) {
72             scanf("%d%c%d%c", &t1, &c1, &t2, &c2);
73             if (c1 == ‘h‘) t1 = t1 * 2 + 1;
74             else t1 = t1 * 2;
75             if (c2 == ‘h‘) t2 = t2 * 2 + 1;
76             else t2 = t2 * 2;
77             if (t1 == 1) add(t2 ^ 1, t2);
78             else if (t2 == 1) add(t1 ^ 1, t1);
79             else if (t1 == 0 || t1 == 0) {}
80             else {
81                 add(t1 ^ 1, t2);
82                 add(t2 ^ 1, t1);
83             }
84         }
85         if (check()) {
86             for (int i = 1 ; i < n ; i++) {
87                 if (ans[i] == i * 2) printf("%dw ", i);
88                 else printf("%dh ", i);
89             }
90             printf("\n");
91         } else printf("bad luck\n");
92
93     }
94     return 0;
95 }

原文地址:https://www.cnblogs.com/qldabiaoge/p/9094461.html

时间: 2024-08-28 22:56:03

poj 3648 Wedding 2-SAT问题入门题目的相关文章

POJ 3648 Wedding (2-SAT+输出可行解)

题目地址:POJ 3648 这题终于AC了....没有专门对新郎新娘加一条边.. 这题前面一直读错题意了,调试了好长时间样例也没过..这题的意思是只要新郎那一边没有通奸的就可以,然后输出新娘那一边的人. 然后就是对那些有**关系的加边,由于新郎新娘必须要在两侧,所以最后要额外加一条边.然后用强连通判断,逆拓扑染色输出可行解即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include

POJ 3648 Wedding(2-SAT 拓扑排序输出任意一种解决方案)

题目链接:http://poj.org/problem?id=3648 Description Up to thirty couples will attend a wedding feast, at which they will be seated on either side of a long table. The bride and groom sit at one end, opposite each other, and the bride wears an elaborate h

poj 3648 Wedding

每对夫妻恰有一人坐在新娘对面,两个关系不正常的人不能都在新娘对面 问,是否有解 #include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include&

UVA 11294 POJ 3648 Wedding

题意: 婚礼上新郎新娘坐在桌子两侧  新娘只能看见对面的人  已知一些人有XX关系-  新娘不想看见有关系的同时坐在对面  问  满足条件的情况下  新娘这边做的人是谁 思路: 新郎那一边的约束最多  有利于解题  那么就变成了  一个人要不要坐新郎这边的2-sat问题  因此可以先求新郎这边的人  然后反一下就是新娘这边的了  注意  新郎是必选点  而且  不能选和新郎有XX关系的- 代码: #include<cstdio> #include<cstring> #include

poj 2186 强连通入门题目

每头牛的梦想就是成为牛群中最受欢迎的牛. 在一群N(1 <= N <= 10,000)母牛中, 你可以得到M(1 <= M <= 50,000)有序的形式对(A,B),告诉你母牛A认为母牛 B很受欢迎. 由于流行是传递性的,如果A认为B很受欢迎,B认为C受欢迎,那么A也会认为C是流行的,即使这不是输入中有序对明确规定的. 你的任务是计算每头奶牛认为受欢迎的奶牛数量. 水题 强连通入门题目. tarjin缩点  然后就变成一棵树, 然后就是求有多少个点的出度为0 输入这个点里面包含的

[poj] The Wedding Juicer | [lintcode] Trapping Rain Water II

问题描述 给定一个二维矩阵,每个元素都有一个正整数值,表示高度.这样构成了一个二维的.有高度的物体.请问该矩阵可以盛放多少水? 相关题目:POJ The Wedding Juicer Description Farmer John's cows have taken a side job designing interesting punch-bowl designs. The designs are created as follows: * A flat board of size W cm

poj 1741 树的点分治(入门)

Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 18205   Accepted: 5951 Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dist(u,v)=The min distance between node u and v. Give an

POJ 2367 Genealogical tree 拓扑排序入门

Description The system of Martians' blood relations is confusing enough. Actually, Martians bud when they want and where they want. They gather together in different groups, so that a Martian can have one parent as well as ten. Nobody will be surpris

dp入门题目

本文文旨,如题... 转载请注明出处... HDOJ 1176 免费馅饼 http://acm.hdu.edu.cn/showproblem.php?pid=1176 类似数塔,从底往上推,每次都是从下面三个中选最大的 1 #include<cstdio> 2 #include<cstring> 3 #define MAXN 100005 4 int dp[MAXN][11];//第i秒第j个位置的馅饼数 5 int max1(int a,int b) 6 { 7 return a