题解:

2-sat

见图还是最难的。。。

每一对有奸情的都建对方连边

代码:

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
const int M=2005,N=3000010;
int head[M],head1[M],edgeNum,edgeNum1,cnt,scnt,begin,n,m,low[M];
int dfn[M],stack[M],id[M],oppo[M],in[M],col[M],instack[M],ans[M];
struct edge{int v,next;}edge[N],edge1[N];
void add(int a,int b)
{
    edge[edgeNum].v=b;
    edge[edgeNum].next=head[a];
    head[a]=edgeNum++;
}
void add1(int a,int b)
{
    edge1[edgeNum1].v=b;
    edge1[edgeNum1].next=head1[a];
    head1[a]=edgeNum1++;
}
void dfs(int x)
{
    low[x]=dfn[x]=++cnt;
    stack[++begin]=x;
    instack[x]=1;
    int v;
    for (int i=head[x];i!=-1;i=edge[i].next)
     {
        v=edge[i].v;
        if (!dfn[v])
         {
            dfs(v);
            low[x]=low[v]<low[x]?low[v]:low[x];
         }
        else if (instack[v]&&dfn[v]<low[x])low[x]=dfn[v];
     }
    if (low[x]==dfn[x])
     {
        scnt++;
        do
         {
            v=stack[begin--];
            instack[v]=0;
            id[v]=scnt;
         }while(v!=x);
     }
    return ;
}
bool solve(int n)
{
    cnt=scnt=begin=0;
    memset(dfn,0,sizeof(dfn));
    memset(instack,0,sizeof(instack));
    for (int i=0;i<2*n;i++)
     if (!dfn[i]) dfs(i);
    for (int i=0;i<n;i++)
     {
        if (id[i]==id[i+n]) return 0;
        oppo[id[i]]=id[i+n];
        oppo[id[i+n]]=id[i];
     }
    memset(in,0,sizeof(in));
    memset(col,0,sizeof(col));
    for (int i=0;i<2*n;i++)
     for (int j=head[i];j!=-1;j=edge[j].next)
      {
        int v=edge[j].v;
        if (id[i]!=id[v])
         {
            in[id[i]]++;
            add1(id[v],id[i]);
         }
      }
    queue<int> que;
    for (int i=0;i<=scnt;i++)
     if (!in[i]) que.push(i);
    while(!que.empty())
     {
        int now=que.front();
        que.pop();
        if (!col[now])
         {
            col[now]=1;
            col[oppo[now]]=-1;
         }
        for (int i=head1[now];i!=-1;i=edge1[i].next)
         {
            int v=edge1[i].v;
            if (--in[v]==0) que.push(v);
         }
     }
    memset(ans,0,sizeof(ans));
    for (int i=0;i<n;i++)
     if (col[id[i]]==1)ans[i]=1;
    return 1;
}
int main()
{
    int a,b;
    char c,d;
    while (scanf("%d%d",&n,&m)!=EOF)
     {
        if (!n&&!m) break;
        edgeNum=edgeNum1=0;
        memset(in,0,sizeof(in));
        memset(id,0,sizeof(id));
        memset(head,-1,sizeof(head));
        memset(head1,-1,sizeof(head1));
        while (m--)
         {
            scanf("%d%c %d%c",&a,&c,&b,&d);
            if (c=='h'&&d=='h'){add(b+n,a);add(a+n,b);}
            if (c=='h'&&d=='w'){add(a+n,b+n);add(b,a);}
            if (c=='w'&&d=='h'){add(a,b);add(b+n,a+n);}
            if (c=='w'&&d=='w'){add(a,b+n);add(b,a+n);}
         }
        add(0,0+n);
        if (solve(n))
         {
            for (int i=1;i<n;i++)
             {
                if (ans[i]) printf("%dh ",i);
                else printf("%dw ",i);
             }
            printf("\n");
         }
        else puts("bad luck");
     }
    return 0;
}

 

posted on 2017-12-25 19:22  宣毅鸣  阅读(121)  评论(0编辑  收藏  举报