poj 3648 Wedding 2sat

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;
}

你可能感兴趣的:(poj 3648 Wedding 2sat)