标签:
http://poj.org/problem?id=3648
题目描述:
有一对新人举办婚礼,邀请了n对夫妇参加他们的婚礼,有一张桌子,人只能坐在桌子的两边。有m对的人通奸(男男,男女,女女),要求:
1.夫妇不能坐在同一边
2.通奸的两个人不能坐在新娘的对面那边
如果存在一组解,则输出坐在新娘同侧的人
分析:
每个人两种状态,坐在桌子的一边或者另一边,有m组矛盾。可以在新郎必选的前提下求出一组解,则这组解为与新郎同侧;反之在新娘必选的前提下求出一组解,则这组解为与新娘同侧。
用2-sat求出一组解,分为值为1和值为0的两部分
//224K 0MS C++
#include<cstring>
#include<cstdio>
#include<queue>
#include<vector>
#include<iostream>
const int MAXN=2010;
const int MAXM=1000010;
using namespace std;
int low[MAXN],dfn[MAXN],sccno[MAXN],scc,dfs_clock,top;
int Stack[MAXN];
bool instack[MAXN];
struct Edge {
int to,next;
} edge[MAXM<<1];int head[MAXN],tot;
void addedge(int u,int v){
edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
}
void init(){
tot=0;
memset(head,0xff,sizeof(head));
}
void dfs(int u){
int v;
low[u]=dfn[u]=++dfs_clock;
instack[u]=1;
Stack[top++]=u;
for(int i=head[u]; i!=-1; i=edge[i].next) {
v=edge[i].to;
if(!dfn[v]) {
dfs(v);
if(low[u]>low[v])
low[u]=low[v];
} else if(instack[v]&&low[u]>dfn[v])
low[u]=dfn[v];
}
if(low[u]==dfn[u]) {
scc++;
for(;;) {
v=Stack[--top];
instack[v]=0;
sccno[v]=scc;
if(v==u) break;
}
}
}
bool solveable(int n){
memset(dfn,0,sizeof(dfn));
memset(instack,false,sizeof(instack));
dfs_clock=top=scc=0;
for(int i=0; i<n; ++i) {
if(!dfn[i]) dfs(i);
}
for(int i=0; i<n; i+=2) {
if(sccno[i]==sccno[i^1]) return false;
}
return true;
}
queue<int> q1;
vector<vector<int> >dag;
char color[MAXN];
int indeg[MAXN];
int cf[MAXN];
void solve(int n){
dag.assign(scc+1,vector<int>());
memset(indeg,0,sizeof(indeg));
memset(color,0,sizeof(color));
for(int u=0;u<n;++u){
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(sccno[u]!=sccno[v]){
dag[sccno[v]].push_back(sccno[u]);
indeg[sccno[u]]++;
}
}
}
for(int i=0;i<n;i+=2){
cf[sccno[i]]=sccno[i^1];
cf[sccno[i^1]]=sccno[i];
}
while(!q1.empty()) q1.pop();
for(int i=1;i<=scc;++i){
if(indeg[i]==0) q1.push(i);
}
while(!q1.empty()){
int u=q1.front();q1.pop();
if(color[u]==0){
color[u]=‘R‘;
color[cf[u]]=‘B‘;
}
int sz=dag[u].size();
for(int i=0;i<sz;++i){
indeg[dag[u][i]]--;
if(indeg[dag[u][i]]==0) q1.push(dag[u][i]);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int n,m,u,v;
char s1,s2;
while(scanf("%d%d",&n,&m)==2) {
if(n==0&&m==0) break;
init();
while(m--){
scanf("%d%c %d%c",&u,&s1,&v,&s2);
u=(s1==‘h‘) ?(2*u+1):(2*u);
v=(s2==‘h‘) ?(2*v+1):(2*v);
// cout<<"u="<<u<<" v="<<v<<endl;
// cout<<"s1="<<s1<<" s2="<<s2<<endl;
addedge(u,v^1);
addedge(v,u^1);
}
addedge(0,1);
if(!solveable(2*n)) puts("bad luck");
else{
solve(2*n);
for(int i=1;i<n;++i){
if(color[sccno[2*i]]==‘R‘) printf("%dh",i);
else printf("%dw",i);
if(i<n-1) printf(" ");
else printf("\n");
}
}
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/u014141559/article/details/45193737