2sat,注意题意。
代码:
#include<iostream>
#include<fstream>
using namespace std;
struct e{
int data;
e *next;
}edge[121],edge2[122];
int n,m;
int v[121],low[121],dfn[121],stack[121],scc[121],tot,index,top;
void tarjan(int s){
int i,j,k;
dfn[s]=low[s]=++index;
stack[++top]=s;
v[s]=1;
e *p=edge[s].next;
while(p){
if(dfn[p->data]==0)
{
tarjan(p->data);
low[s]=min(low[s],low[p->data]);
}
else
if(v[p->data])
{
low[s]=min(low[s],dfn[p->data]);
}
p=p->next;
}
if(low[s]==dfn[s]){
++tot;
do{
i=stack[top--];
scc[i]=tot;
v[i]=0;
}while(i!=s);
}
}
void solve(){
int i,j,k;
index=0;tot=0;top=0;
memset(v,0,sizeof(v));
memset(dfn,0,sizeof(dfn));
for(i=0;i<4*n;i++)
if(dfn[i]==0)
tarjan(i);
}
void build(){
int i,j,k;
memset(edge2,0,sizeof(edge2));
for(i=0;i<4*n;i++)
{
e *p=edge[i].next;
while(p){
if(scc[p->data]!=scc[i])
{
e *q=new e;
q->data=scc[i];
q->next=edge2[scc[p->data]].next;
edge2[scc[p->data]].next=q;
}
p=p->next;
}
}
}
int queue[130];
void dfs(int s){
int i,j,k;
v[s]=1;
e *p=edge2[s].next;
while(p){
if(v[p->data]==0)
dfs(p->data);
p=p->next;
}
queue[top++]=s;
}
int ant[130];
void solve1(){
int i,j,k;
for(i=0;i<2*n;i++)
{
ant[scc[i]]=scc[i+2*n];
ant[scc[i+2*n]]=scc[i];
}
build();
top=0;
for(i=0;i<tot;i++)
if(v[i]==0)
dfs(i);
memset(v,0,sizeof(v));
for(i=top-1;i>=0;i--)
{
j=queue[i];
if(v[j]==0)
{
v[j]=1;
v[ant[j]]=2;
j=ant[j];
e *p=edge2[j].next;
while(p){
v[p->data]=2;
p=p->next;
}
}
}
for(i=1;i<n;i++)
if(v[scc[i]]==1)
cout<<i<<"w ";
for(i=n;i<2*n;i++)
if(v[scc[i]]==1)
cout<<i-n<<"h ";
cout<<endl;
}
void read(){
// ifstream cin("in.txt");
int i,j,k,s;
while(1){
cin>>n>>m;
if(n==0&&m==0) return;
memset(edge,0,sizeof(edge));
s=2*n;
e *p=new e;
p->data=0;
p->next=edge[n].next;
edge[n].next=p;
e *q=new e;
q->data=3*n;
q->next=edge[2*n].next;
edge[2*n].next=q;
for(i=0;i<n;i++)
{
e *p=new e;
p->data=i+s;
p->next=edge[i+n].next;
edge[i+n].next=p;
e*q=new e;
q->data=i;
q->next=edge[i+n+s].next;
edge[i+n+s].next=q;
e*p1=new e;
p1->data=i+n;
p1->next=edge[i+s].next;
edge[i+s].next=p1;
e *q1=new e;
q1->data=i+n+s;
q1->next=edge[i].next;
edge[i].next=q1;
}
char c1,c2;
for(i=1;i<=m;i++)
{
cin>>j>>c1>>k>>c2;
if(c1=='h') j+=n;
if(c2=='h') k+=n;
e *p=new e;
p->data=k;
p->next=edge[j+s].next;
edge[j+s].next=p;
e *q=new e;
q->data=j;
q->next=edge[k+s].next;
edge[k+s].next=q;
}
solve();
for(i=1;i<=n*2;i++)
if(scc[i]==scc[i+s])
break;
if(i<=n*2)
{
cout<<"bad luck"<<endl;
continue;
}
else
{
solve1();
}
}
}
int main(){
read();
return 0;
}