标签:style blog class code int string 2014 set 404 name har
英文太差了, 这个题目愣是半天没看懂 , 后面看别人翻译才看懂 , 英语是硬伤啊
题目大意:给 n 对夫妇安排座位 , 0h , 0w表示新郎新娘 , 新娘只能看到坐在她对面那一排的人 , 要求:
1、同一对新郎新娘不能做在同一侧
2、有m对人互为通奸(可以男男、女女、男女) , 新娘不能同时看到互为通奸的两个人。
注意:新郎也有可能和其他人通奸
做法:
1、分两种情况讨论 , 新娘在左侧 , 新娘在右侧 , 分别建图进行 2-SAT算法
2、不分左侧还是右侧 , 只分和新娘同侧或不同侧
下面给出做法一的代码
#include <iostream>
#include <vector>
#include <stdio.h>
#include <string.h>
using namespace std;
#define maxn 200000
int n , m;
int a[maxn][2];
vector<int>grap[maxn];
bool mark[maxn];
int s[maxn];
int c;
void init()
{
memset(mark , 0 , sizeof(mark));
for(int i = 0; i < 4*n; i++)
grap[i].clear();
}
void add_edge(int x , int y)
{
grap[x].push_back(y);
//cout<<x<<",,"<<y<<endl;
}
bool dfs(int u)
{
if(mark[u^1]) return false;
if(mark[u]) return true;
mark[u] = true;
s[c++] = u;
for(int i = 0; i < grap[u].size(); i++)
{
if(!dfs(grap[u][i])) return false;
}
return true;
}
bool slove()
{
int i;
for(i = 0; i < n*4; i += 2)
{
if(!mark[i] && !mark[i+1])
{
c = 0;
if(!dfs(i))
{
while(c > 0) mark[s[--c]] = false;
if(!dfs(i+1)) return false;
}
}
}
return true;
}
void print(int i)
{
int bz = true;
for( ; i < 4*n ; i += 2)
{
if(i == 2*n || i == 2*n+1) continue;
if(mark[i])
{
if(i >= 2*n)
{
if(bz) printf("%dh" , (i-2*n)/2) , bz = false;
else printf("% dh" , (i-2*n)/2);
}
else
{
if(bz) printf("%dw" , i/2) , bz = false;
else printf("% dw" , i/2);
}
}
}
cout<<endl;
}
int main()
{
while(scanf("%d %d" , &n , &m) != EOF)
{
if(n == 0 && m == 0) break;
//n -= 1;
init();
int i ;
int x , y;
char px , py;
for(i = 0; i < m; i++)
{
scanf("%d%c %d%c" , &x , &px , &y , &py);
//x -= 1; y -= 1;
if(px == ‘h‘) a[i][0] = 2*n+x*2;
else a[i][0] = x*2;
if(py == ‘h‘) a[i][1] = 2*n+y*2;
else a[i][1] = y*2;
}
for(i = 2; i < 2*n; i += 2) //夫妻之间
{
add_edge(i , 2*n+i+1);
add_edge(2*n+i+1,i );
add_edge(i+1 , 2*n+i);
add_edge(2*n+i , i+1);
}
for(i = 0; i < m; i++) //仇人之间
{
add_edge(a[i][0]+1 , a[i][1]);
add_edge(a[i][1]+1 , a[i][0]);
}
mark[0] = mark[2*n+1] = true;
bool bz = slove();
if(!bz)
{
init();
for(i = 0; i < 2*n; i += 2) //夫妻之间
{
add_edge(i , 2*n+i+1);
add_edge(2*n+i+1 ,i );
add_edge(i+1 , 2*n+i);
add_edge(2*n+i , i+1);
}
for(i = 0; i < m; i++) //仇人之间
{
add_edge(a[i][0] , a[i][1]+1);
add_edge(a[i][1] , a[i][0]+1);
}
mark[1] = mark[2*n] = true;
bz = slove();
if(!bz) printf("bad luck\n");
else
{
print(3);
}
}
else
{
print(2);
}
}
return 0;
}
uva 11294 2-SAT问题,码迷,mamicode.com
标签:style blog class code int string 2014 set 404 name har
原文地址:http://blog.csdn.net/zengchen__acmer/article/details/24742895