poj 3648 Wedding
来源:互联网 发布:人工智能医疗股票龙头 编辑:程序博客网 时间:2024/06/03 03:31
类型:2-sat
题目:http://poj.org/problem?id=3648
来源:Waterloo Local Contest, 2007.9.29
思路:每个人都有可能坐在左边或者右边,将其分为两个点i, i + 2 * n。定义新娘在左侧。
(1)对于一对有暧昧关系的人i, j。如果i在右边,必有j在左边,如果j在右边,必有i在左边。构造有向边: addedge1(i + 2 * n, j); addedge1(j + 2 * n, i)。
(2)夫妇需一左一右
然后通过2-sat算法判断可行性,如果可行并输出解。
!!!新娘必在左边,新郎必在右边。构造有向边 addedge1(2 * n + 1, 1); addedge1(n + 1, 3 * n + 1);
// poj 3648 Wedding// wa wa ac 196K 0MS#include <iostream>#include <string>#include <queue>#include <stack>#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define FOR(i,a,b) for(i = (a); i < (b); ++i)#define FORE(i,a,b) for(i = (a); i <= (b); ++i)#define FORD(i,a,b) for(i = (a); i > (b); --i)#define FORDE(i,a,b) for(i = (a); i >= (b); --i)#define CLR(a,b) memset(a,b,sizeof(a))#define PB(x) push_back(x)const int N = 200;const int M = 40010;int low[N], dfn[N];int belong[N];bool inStack[N], vis[N];stack<int> st;int n, m;int step, t;int conflict[N];//缩点后有矛盾的点int du[N];//入度int color[N];//1为红色,-1为蓝色,红色输出int cnt1, cnt2;int head1[N], head2[N];int top[N], cnt;struct node { int s, e; int len;}c[N];struct edge1 { int v, nxt;}E1[M];struct edge2 { int v, nxt;}E2[M];void addedge1(int u, int v) { E1[cnt1].v = v; E1[cnt1].nxt = head1[u]; head1[u] = cnt1++;}void addedge2(int u, int v) { E2[cnt2].v = v; E2[cnt2].nxt = head2[u]; head2[u] = cnt2++;}void tarjan(int u) { int i; step++; st.push(u); low[u] = dfn[u] = step; vis[u] = 1; inStack[u] = 1; for(i = head1[u]; i != -1; i = E1[i].nxt) { int x = E1[i].v; if(!vis[x]) { tarjan(x); low[u] = min(low[u], low[x]); } else if(inStack[x]) low[u]=min(low[u], dfn[x]); } if(low[u] == dfn[u]) { t++; while(1) { int x = st.top(); st.pop(); belong[x] = t; inStack[x] = 0; if(x == u) break; } }}void init() { cnt1 = cnt2 = step = t = 0; CLR(head1, -1); CLR(head2, -1); CLR(du, 0); CLR(color, 0); CLR(vis, 0); CLR(inStack, 0);}bool isConflict(int a, int b, int c, int d) { if(a >= d || b <= c) return false; return true;}void Rebuild(){//逆图 int i, j; FORE(i, 1, 4 * n) { for(j = head1[i]; j != -1; j = E1[j].nxt) { int a = belong[i], b = belong[E1[j].v]; if(a != b) { addedge2(b, a); du[a]++; } } } FORE(i, 1, 2 * n) { int a = belong[i], b = belong[i + 2 * n]; conflict[a] = b; conflict[b] = a; }}void topsort() { int i,j; queue<int> q; FORE(i, 1, t) if(du[i] == 0) q.push(i); cnt = 0; while(!q.empty()) { int x = q.front(); top[++cnt] = x; q.pop(); for(i = head2[x]; i != -1; i = E2[i].nxt) { int tmp = E2[i].v; du[tmp]--; if(du[tmp] == 0) q.push(tmp); } }}void dfs_Blue(int u) { int i; color[u] = -1; for(i = head2[u]; i != -1; i = E2[i].nxt) { int x = E2[i].v; if(color[x] == 0) dfs_Blue(x); }}void dfs_Red() { int i, j; FORE(i, 1, cnt) { int x = top[i]; if(color[x] == 0) { color[x] = 1; dfs_Blue(conflict[x]); } }}void output() { int i, j, t1, t2; int len = 0; int sign = color[belong[1]]; FORE(i, 2, 2 * n) { int x = belong[i], y = belong[i + 2 * n]; if(color[x] == sign) { if(i <= n) (len++ == 0) ? printf("%dw", i - 1) : printf(" %dw", i - 1); else (len++ == 0) ? printf("%dh", i - n - 1) : printf(" %dh", i - n - 1); } } printf("\n");}void solve() { int i, j; FORE(i, 1, 4 * n) if(!vis[i]) tarjan(i); FORE(i, 1, 2 * n) { if(belong[i] == belong[i + 2 * n]) { printf("bad luck\n"); return ; } } Rebuild(); topsort(); dfs_Red(); output();}int main() { char str1[5], str2[5]; while(scanf("%d %d", &n, &m) != EOF, n || m) { init(); int i, j, t1, t2; FORE(i, 1, m) { scanf("%d%c%d%c", &t1, &str1[0], &t2, &str2[0]); ++t1, ++t2; if(str1[0] == 'h') t1 += n; if(str2[0] == 'h') t2 += n; addedge1(t1 + 2 * n, t2); addedge1(t2 + 2 * n, t1); } addedge1(2 * n + 1, 1); addedge1(n + 1, 3 * n + 1); FORE(i, 1, n) { addedge1(i, i + 3 * n); addedge1(i + 2 * n, i + n); addedge1(i + n, i + 2 * n); addedge1(i + 3 * n, i); } solve(); } return 0;}
- POJ 3648 Wedding
- poj 3648 Wedding
- poj 3648 wedding
- poj 3648 Wedding
- poj 3648 Wedding
- poj 3648 Wedding
- POJ 3648 Wedding
- poj 3648 Wedding 2sat
- poj 3648 Wedding 2-SAT
- 2-sat->poj 3648 Wedding
- POJ 3648 Wedding(2-SAT)
- 【POJ】3648 Wedding 2-sat
- UVA 11294 POJ 3648 Wedding
- poj 3648 Wedding 2-sat
- POJ 3648 Wedding 2-SAT
- poj 3648 Wedding 2_SAT
- POJ 3648Wedding 2-sat
- |poj 3648|2-SAT|Wedding
- 故招的必定后被解雇
- SDL API
- More on Visual Studio and .NET version numbering
- LNB investigation
- sql server 的部分基本用法。
- poj 3648 Wedding
- Oracle 9i加载数据库出错的解决方法
- 抽象类和接口的一些特征
- android button组件居中显示
- byte[]转换成InputStream
- 黑马程序员_第四天
- T-SQL
- CATransform3D 矩阵 m11–m44每个的含义
- 好网站收集