• 废水回收


      

    2-SAT,复杂度是O(m),每个点分成2个点,代表选或者不选,然后建图有个原则,就是一条有向边x->y代表x选了y必选,然后建图完tarjan,如果有2个点在同一个环中,无解,否则建立反向图拓扑排序,搜到一个点,就把他对立点和后继全部选为不选。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<vector>
     7 int tot,go[200005],first[200005],next[200005];
     8 int instack[200005],num,sz,low[200005],dfn[200005];
     9 int vis[200005],st[200005],top;
    10 int c[200005],belong[200005],n,m,ru[200005],op[200005],col[200005];
    11 std::vector<int> son[200005];
    12 int read(){
    13     int t=0,f=1;char ch=getchar();
    14     while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    15     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    16     return t*f;
    17 }
    18 void insert(int x,int y){
    19     tot++;
    20     go[tot]=y;
    21     next[tot]=first[x];
    22     first[x]=tot;
    23 }
    24 void tarjan(int x){
    25     instack[x]=1;low[x]=dfn[x]=++sz;
    26     vis[x]=1;st[++top]=x;
    27     for (int i=first[x];i;i=next[i]){
    28         int pur=go[i];
    29         if (!vis[pur]){
    30             tarjan(pur);
    31             low[x]=std::min(low[x],low[pur]);
    32         }else if (instack[pur]){
    33             low[x]=std::min(low[x],dfn[pur]);
    34         }
    35     }
    36     if (low[x]==dfn[x]){
    37         num++;
    38         while (st[top]!=x){
    39             instack[st[top]]=0;
    40             belong[st[top]]=num;
    41             top--;
    42         }
    43         instack[x]=0;
    44         belong[x]=num;
    45         top--;
    46     }
    47 }
    48 void dfs(int x){
    49     if (col[x]) return;col[x]=-1;
    50     for (int i=0;i<son[x].size();i++){
    51         dfs(son[x][i]);
    52     }
    53 }
    54 void solve(){
    55     int t=0;
    56     for (int i=1;i<=num;i++) if (!ru[i]) c[++t]=i;
    57     while (t){
    58         int now=c[t--];
    59         if (col[now]) continue;
    60         col[now]=1;
    61         dfs(op[now]);
    62         for (int i=0;i<son[now].size();i++){
    63             if (!(--ru[son[now][i]])) c[++t]=son[now][i];
    64         }
    65     }
    66 }
    67 int main(){
    68     freopen("gates.in","r",stdin);
    69     freopen("gates.out","w",stdout);
    70     n=read();m=read();
    71     for (int i=1;i<=n;i++){
    72         int a=read(),sa=read(),b=read(),sb=read();
    73         if (sa==0){
    74             if (sb==0) insert(a<<1,(b<<1)-1),insert(b<<1,(a<<1)-1);
    75             else insert(a<<1,b<<1),insert((b<<1)-1,(a<<1)-1);
    76         }else{
    77             if (sb==0) insert((a<<1)-1,(b<<1)-1),insert(b<<1,a<<1);
    78             else insert((a<<1)-1,b<<1),insert((b<<1)-1,a<<1);
    79         }
    80     }
    81     for (int i=1;i<=m<<1;i++) if (!vis[i]) tarjan(i);
    82     for (int i=1;i<=m;i++)
    83      if (belong[(i<<1)-1]==belong[i<<1]){
    84             puts("IMPOSSIBLE");
    85             return 0;
    86      }
    87     for (int i=1;i<=m<<1;i++) 
    88      for (int j=first[i];j;j=next[j]){
    89             int pur=go[j];
    90             if (belong[pur]==belong[i]) continue;
    91             son[belong[pur]].push_back(belong[i]);
    92             ru[belong[i]]++;
    93      }
    94     for (int i=1;i<=m;i++)
    95      op[belong[i<<1]]=belong[(i<<1)-1],op[belong[(i<<1)-1]]=belong[i<<1];
    96     solve();
    97     for (int i=1;i<=m;i++) if (col[belong[i<<1]]==1) puts("1");else puts("0");  
    98 }
  • 相关阅读:
    【项目】项目236
    【项目】项目237
    【项目】项目238
    【项目】项目233
    【项目】项目235
    【项目】项目231
    Windows10系统MySQL5.7升级到8.0
    对接口限流方案
    工作中项目涉及的小细节,你都遇到了吗
    62.Mysql的binlog清除方法
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5635372.html
Copyright © 2020-2023  润新知