zoukankan      html  css  js  c++  java
  • 【模板】2-SAT 问题

    题面

    https://www.luogu.org/problem/P4782

    题解

    输出时,要输出所属强连通分量的字典序最小的点,而且经实测,改了就错。

    因为一个联通块,缩了点形成一个$DAG$,我们肯定要输出$DAG$上拓扑序靠后的$DAG$(附加条件更少),有因为$tarjan$是正着搜的,拓扑序靠后的强连通分量先被判定,字典序更小。

    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<stack>
    #include<cstdlib>
    
    using namespace std;
    
    int n,m,clo=0,cnt=0;
    int dfn[2000050],low[2000050],bel[2000050];
    vector<int> to[2000050];
    stack<int> stk;
    bool ins[2000050],sat[1000050],vis[2000050];
    
    void tarjan(int x){
      int i,y,l=to[x].size();
      dfn[x]=low[x]=++clo;
      ins[x]=true;
      stk.push(x);
      for (i=0;i<l;i++) {
        if (!dfn[to[x][i]]) {
          tarjan(to[x][i]);
          low[x]=min(low[x],low[to[x][i]]);
        }
        else if (ins[to[x][i]]) {
          low[x]=min(low[x],dfn[to[x][i]]);
        }
      }
      if (dfn[x]==low[x]) {
        ++cnt;
        int opt=(x-1)/n;
        int num=x-opt*n;
        do {
          y=stk.top();
          stk.pop();
          bel[y]=cnt;
          ins[y]=false;
        } while (y!=x);
      }
    }
    
    void dfs(int x){
      if (vis[x]) return;
      vis[x]=true;
      if (x>n) sat[x-n]=1; else sat[x]=0;
      int i,l=to[x].size();
      for (i=0;i<l;i++) if (!vis[to[x][i]])dfs(to[x][i]);
    }
    
    int main(){
      int i,u,v,opt1,opt2;
      scanf("%d %d",&n,&m);
      for (i=1;i<=m;i++) {
        scanf("%d %d %d %d",&u,&opt1,&v,&opt2);
        to[(!opt1)*n+u].push_back(opt2*n+v);
        to[(!opt2)*n+v].push_back(opt1*n+u);
      }
      for (i=1;i<=2*n;i++) if (!dfn[i]) tarjan(i);
      for (i=1;i<=n;i++) if (bel[i]==bel[n+i]) {
        puts("IMPOSSIBLE");
        return 0;
      }
      puts("POSSIBLE");
      for (i=1;i<=n;i++) if (bel[i]<bel[n+i]) dfs(i); else dfs(n+i);
      for (i=1;i<=n;i++) printf("%d ",sat[i]);
    }
  • 相关阅读:
    数据结构学习8——二叉树的销毁
    单链表的反向
    LNK4098: 默认库“MSVCRT”与其他库的使用冲突
    动态链接库(VC_Win32)
    注册表操作(VC_Win32)
    消息钩子与定时器(VC_Win32)
    套接字编程(VC_Win32)
    线程概述,优先级,睡眠,创建及终止(VC_Win32)
    进程通信(VC_Win32)
    进程概述及创建,终止(VC_Win32)
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11349879.html
Copyright © 2011-2022 走看看