zoukankan      html  css  js  c++  java
  • Gym

    之前的解法

    其实二分图染色问题可以看成2-SAT问题的一个特例,只需要稍微修改一下板子,在对每个连通块dfs的时候每个点黑白都试一下,取个最小值即可,因为二分图染色比较特殊,各个连通块相互独立,因此不存在回溯的问题(一般情况下2-SAT问题对每个点的黑白染色都分别判断的话需要回溯)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef double db;
     5 const int N=2e5+10,inf=0x3f3f3f3f;
     6 struct TWO_SAT {
     7     int n,hd[N],ne,col[N],sta[N],tp;
     8     struct E {int v,f,g,nxt;} e[N*4];
     9     void link(int u,int v,int f,int g) {
    10         e[ne]= {v,f,g,hd[u]},hd[u]=ne++;
    11         e[ne]= {u,!g,!f,hd[v]},hd[v]=ne++;
    12     }
    13     void init(int _n) {
    14         n=_n,ne=tp=0;
    15         for(int i=1; i<=n; ++i)hd[i]=-1;
    16     }
    17     bool dfs(int u,int c) {
    18         if(~col[u])return col[u]==c;
    19         col[u]=c,sta[tp++]=u;
    20         for(int i=hd[u]; ~i; i=e[i].nxt) {
    21             int v=e[i].v,f=e[i].f,g=e[i].g;
    22             if(f==col[u]&&!dfs(v,g))return 0;
    23         }
    24         return 1;
    25     }
    26     int check() {
    27         int ret=0;
    28         for(int i=1; i<=n; ++i)col[i]=-1;
    29         for(int i=1; i<=n; ++i)if(!~col[i]) {
    30                 tp=0;
    31                 int mi=inf;
    32                 if(dfs(i,0)) {
    33                     int cnt=0;
    34                     for(int i=0; i<tp; ++i)if(col[sta[i]]==1)++cnt;
    35                     mi=min(mi,cnt);
    36                 }
    37                 for(; tp; col[sta[--tp]]=-1);
    38                 if(dfs(i,1)) {
    39                     int cnt=0;
    40                     for(int i=0; i<tp; ++i)if(col[sta[i]]==1)++cnt;
    41                     mi=min(mi,cnt);
    42                 } else {
    43                     for(; tp; col[sta[--tp]]=-1);
    44                     dfs(i,0);
    45                 }
    46                 if(mi==inf)return -1;
    47                 ret+=mi;
    48             }
    49         return ret;
    50     }
    51 } twosat;
    52 int n,m;
    53 
    54 int main() {
    55     scanf("%d%d",&n,&m);
    56     twosat.init(n);
    57     while(m--) {
    58         int u,v,c;
    59         scanf("%d%d%d",&u,&v,&c);
    60         if(c==0)twosat.link(u,u,1,0),twosat.link(v,v,1,0);
    61         else if(c==1)twosat.link(u,v,1,0),twosat.link(u,v,0,1);
    62         else if(c==2)twosat.link(u,u,0,1),twosat.link(v,v,0,1);
    63     }
    64     int ans=twosat.check();
    65     if(ans==-1)puts("impossible");
    66     else printf("%d
    ",ans);
    67     return 0;
    68 }
  • 相关阅读:
    Linux下MySQL数据库常用基本操作 一
    Cdnbes负载均衡的权重用法解释
    docker安装
    centos网卡配置和防火墙停止和启动
    Excel 如何锁定表头
    权值线段树 基础入门知识详解
    JZOJ 3362. 【NOI2013模拟】数数(DFS)
    JZOJ 3348. 【NOI2013模拟】秘密任务(最短路+最小割唯一性)
    JZOJ 3303. 【集训队互测2013】城市规划(卷积+分治NTT)
    FFT快速傅里叶变换(超详细的入门学习总结)
  • 原文地址:https://www.cnblogs.com/asdfsag/p/14611396.html
Copyright © 2011-2022 走看看