zoukankan      html  css  js  c++  java
  • poj3648

    题解:

    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("
    ");
             }
            else puts("bad luck");
         }
        return 0;
    }
  • 相关阅读:
    fread()创建文件和file_exists()文件缓存问题
    docker 常用命令(一)
    python学习资源
    python 爬虫之 selenium API
    卡方检验用于特征选择
    三种常用数据标准化方法
    oracle查看编码以及修改编码
    JAVA 泛型
    java中Class对象详解和类名.class, class.forName(), getClass()区别
    oracle 数据导入导出
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8110830.html
Copyright © 2011-2022 走看看