2sat
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=30*2+9;
int n,m;
int head[maxn];
int lon;
int dfn[maxn],low[maxn],stack[maxn],instack[maxn],s[maxn],un[maxn];
int count,top,con;
int head2[maxn],in[maxn],to[maxn],totop;
int col[maxn];
struct
{
int next,to;
}e[100000];
void edgemake(int from,int to,int head[])
{
e[++lon].to=to;
e[lon].next=head[from];
head[from]=lon;
}
void edgeini()
{
memset(head,-1,sizeof(head));
lon=-1;
}
void tarjan(int t)
{
dfn[t]=low[t]=++count;
instack[t]=1;
stack[++top]=t;
for(int k=head[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(dfn[u]==-1)
{
tarjan(u);
low[t]=min(low[t],low[u]);
}
else if(instack[u])
low[t]=min(low[t],dfn[u]);
}
if(dfn[t]==low[t])
{
++con;
while(1)
{
int u=stack[top--];
instack[u]=0;
s[u]=con;
edgemake(con,u,un);
if(u==t) break;
}
}
}
void tarjan()
{
memset(dfn,-1,sizeof(dfn));
memset(instack,0,sizeof(instack));
memset(un,-1,sizeof(un));
count=top=con=0;
for(int i=0;i<n+n;i++)
if(dfn[i]==-1)
tarjan(i);
}
bool check()
{
for(int i=0;i<n+n;i++)
if(s[i]==s[i^1])
return false;
return true;
}
void makegraph()
{
memset(head2,-1,sizeof(head2));
for(int i=0;i<n+n;i++)
for(int k=head[i];k!=-1;k=e[k].next)
if(s[i]!=s[e[k].to])
edgemake(s[e[k].to],s[i],head2);
}
void topo()
{
memset(in,0,sizeof(in));
top=totop=0;
for(int i=1;i<=con;i++)
for(int k=head[i];k!=-1;k=e[k].next)
in[e[k].to]++;
for(int i=1;i<=con;i++)
if(in[i]==0)
stack[++top]=i;
while(top)
{
int u=stack[top--];
to[++totop]=u;
for(int k=head2[u];k!=-1;k=e[k].next)
{
int v=e[k].to;
in[v]--;
if(in[v]==0)
{
stack[++top]=v;
}
}
}
}
void paint(int t)
{
for(int k=head2[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(col[u]==-1)
{
col[u]=0;
paint(u);
}
}
}
void colour()
{
memset(col,-1,sizeof(col));
for(int i=1;i<=con;i++)
if(col[i]==-1)
{
col[i]=1;
for(int k=un[i];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(col[s[u^1]]==-1)
{
col[s[u^1]]=0;
paint(s[u^1]);
}
}
}
}
int main()
{
while(scanf("%d %d",&n,&m),n&&m)
{
edgeini();
for(int i=1,from,to;i<=m;i++)
{
char txt,tmp;
scanf("%d %c %d %c",&from,&tmp,&to,&txt);
from*=2;
to*=2;
if(tmp=='w') from++;
if(txt=='w') to++;
edgemake(from,to^1,head);
edgemake(to,from^1,head);
}
edgemake(1,0,head);
edgemake(0,0,head);
tarjan();
if(!check())
{
printf("bad luck\n");
continue;
}
makegraph();
topo();
colour();
for(int i=2;i<n+n-2;i+=2)
if(col[s[i]]==0)
{
printf("%dh ",i/2);
}
else
printf("%dw ",i/2);
if(col[s[n+n-2]]==0)
printf("%dh ",(n+n-2)/2);
else
printf("%dw ",(n+n-2)/2);
printf("\n");
}
return 0;
}
5686

被折叠的 条评论
为什么被折叠?



