zoukankan      html  css  js  c++  java
  • LOJ-10097(2-sat问题)

    题目链接:传送门

    思路:

    2-sat问题,如果选每个集合最多有两个元素,eg:(Ai,Ai’),(Bi,Bi’);

    如果Ai,Bi冲突,就只能选Ai,Bi’(建立边),然后缩点,查找有无相同集合的点在同一个集合中。

    然后将区块节点较小的先输出。

    具体的2-sat问题(还是比较懵)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 200200;
    int low[maxn],num[maxn],tot,co[maxn],col;
    int st[maxn],top;
    int fa[maxn],vis[maxn];
    int head[maxn],ver[maxn],next[maxn],tim;
    int MIN(int x,int y)
    {
        return x<y?x:y;
    }
    void Init()
    {
        memset(fa,0,sizeof(fa));
        memset(vis,0,sizeof(vis));
        memset(head,0,sizeof(head));
        top=0;tot=0;col=0;tim=0;
    }
    void addedge(int u,int v)
    {
        ver[++tot]=v;next[tot]=head[u];head[u]=tot;
    }
    void Tarjan(int u)
    {
        low[u]=num[u]=++tim;
        st[++top]=u;
        for(int i=head[u];i;i=next[i]){
            int v=ver[i];
            if(!num[v]){
                Tarjan(v);
                low[u]=MIN(low[u],low[v]);
            }
            else if(!co[v]) low[u]=MIN(low[u],num[v]);
        }
        if(low[u]==num[u]){
            col++;
            co[u]=col;
            while(st[top]!=u){
                co[st[top]]=col;
                top--;
            }
            top--;
        }
    }
    int main(void)
    {
        int i,j,m,n,x,y;
        while(~scanf("%d%d",&n,&m)){
            Init();
            for(i=1;i<=m;i++){
                scanf("%d%d",&x,&y);
                addedge(x,(y%2==0?y-1:y+1));
                addedge(y,(x%2==0?x-1:x+1));
            }
            for(i=1;i<=n*2;i++)
            if(!num[i]) Tarjan(i);
            
            int fg=0;
            for(i=1;i<=n*2;i+=2){
                if(co[i]==co[i+1]){
                    printf("NIE
    ");fg=1;break;
                }
                fa[i]=i+1;fa[i+1]=i;
            }
            if(fg==1) continue;
            for(i=1;i<=n*2;i++) vis[i]=(co[i]>co[fa[i]]?1:0);
            for(i=1;i<=n*2;i++){
                if(!vis[i]) printf("%d
    ",i);
            }
        }
        return 0;
    }
    View Code

    参考文章:传送门

  • 相关阅读:
    ES6对象的扩展
    ES6函数的扩展
    ES6新增变量
    ES6框架的搭建
    自适应布局 左右结构、上下结构
    iframe 子页面改变父页面样式
    检测终端类型
    $.grep()
    点击元素内部不隐藏,点击元素外部元素隐藏
    angular表单验证
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10373076.html
Copyright © 2011-2022 走看看