zoukankan      html  css  js  c++  java
  • Peaceful Commission 2-sat

      n个国家  每个国家有两个代表  桥求选出 n个人成立世界和平委员会    有m条关系    a与b 关系差不能同时选中    求选中人的最小字典序 

    2-sat的入门题

    调试了半天发现那个博客就是错的心态崩了

    #include<bits/stdc++.h>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=16000;
    const int M=5*N;
     int n,m;
    int pos,head[N],pos2,head2[N];
    struct Edge
    {
        int to,nex;
    }edge[M],edge2[M];
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].to=b;
    }
    void add2(int a,int b)
    {
        edge2[++pos2].nex=head2[a];
        head2[a]=pos2;
        edge2[pos2].to=b;
    }
    
    int tot,ind,cnt,Stack[N],dfn[N],low[N],belong[N],in[N],vis[N];
    int f[N];
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tot;
        Stack[++ind]=x;
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(vis[v])
                low[x]=min(low[x],low[v]);
        }
        if(dfn[x]==low[x])
        {
            cnt++;int v;
            do
            {
                v=Stack[ind--];
                vis[v]=0;
                belong[v]=cnt;
            }
            while(v!=x);
        }
    }
    int ans[N];
    void init()
    {
        cnt=pos=ind=tot=pos2=0;
        CLR(head2,0);
        CLR(head,0);
        CLR(vis,0);
        CLR(in,0);
        CLR(Stack,0);
        CLR(dfn,0);
        CLR(low,0);
        CLR(ans,0);
    }
    
    void builddag()
    {
        rep(i,0,2*n-1)
        {
            int u=belong[i];
            for(int j=head[i];j;j=edge[j].nex)
            {
                int v=belong[edge[j].to];
                if(v!=u)
                    add2(v,u),in[u]++;
            }
        }
    }
    
    void solve()
    {
        for(int i=0;i<2*n;i+=2)
            if(belong[i]==belong[i^1])
            {
                printf("NIE
    ");
                return ;
            }
            else
                f[ belong[i] ]=belong[i+1],f[belong[i+1]]=belong[i];
    
         builddag();
        queue<int>q;
        rep(i,1,cnt)
        if(!in[i])
            q.push(i);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            if(!ans[u])
                ans[u]=1,ans[f[u]]=2;
            for(int i=head2[u];i;i=edge2[i].nex)
            {
                int v=edge2[i].to;
                if(--in[v]==0)q.push(v);
            }
        }
        for(int i=0;i<2*n;i+=2)
        if(ans[belong[i]]==1)
            printf("%d
    ",i+1);
        else printf("%d
    ",i+2);
    }
    
    int main()
    {
        while(RII(n,m)==2)
        {
            init();
            rep(i,1,m)
            {
                int a,b;RII(a,b);
                b--;a--;add(a,b^1);add(b,a^1);
            }
            rep(i,0,2*n-1)
            if(!dfn[i])
                tarjan(i);
            solve();
    
        }
        return 0;
    }
    View Code

    贴上2-sat模板:

    #include<bits/stdc++.h>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=8005*2;
    const int M=90000;
    int n,m;
    int head[M<<1],pos;
    struct Edge
    {
        int to,nex;
    }edge[M<<1];
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].to=b;
    }
    void init()
    {
        pos=0;
        CLR(head,0);
    }
    int cnt,vis[N],s[N];
    bool dfs(int x)
    {
        if(vis[x^1])return 0;
        if(vis[x])return 1;
        s[cnt++]=x;
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].nex)
            if(!dfs(edge[i].to))
            return 0;
        return 1;
    }
    bool twosat()
    {
        CLR(vis,0);
        for(int i=0;i<2*n;i+=2)
        if(!vis[i]&&!vis[i+1]){
            cnt=0;
            if(!dfs(i)){
            while(cnt)vis[ s[--cnt] ]=0;
            if(!dfs(i^1))return 0;
            }
        }
        return 1;
    }
    int main()
    {
        int a,b;
        while(RII(n,m)!=EOF)
        {
            init();
            rep(i,1,m)
            {
                RII(a,b);
                a--;b--;
                add(a,b^1);
                add(b,a^1);
            }
            if(twosat())
            {
                for(int i=0;i<2*n;i+=2)
                {
                    if(vis[i])printf("%d
    ",i+1);
                    else printf("%d
    ",i+2);
                }
            }
            else printf("NIE
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    windows下用cmd命令netstat查看系统端口使用情况
    linux 运维知识体系
    Oracle中MD5+Base64加密实现
    MySql学习—— 查询性能优化 深入理解MySql如何执行查询
    Mysql集群和主从
    Docker搭建 oracle
    docker容器以ROOT账号登录(获取ROOT权限/ROOT密码)
    一文看懂javaGC
    Docker 国内仓库和镜像
    排序算法___堆排序
  • 原文地址:https://www.cnblogs.com/bxd123/p/10801709.html
Copyright © 2011-2022 走看看