当前位置 : 主页 > 网页制作 > HTTP/TCP >

【模板】 2-sat

来源:互联网 收集:自由互联 发布时间:2021-06-16
1 // https://blog.csdn.net/jarjingx/article/details/8521690 2 // 上面是讲解,下面是代码 3 // https://www.e-learn.cn/content/qita/1061337 4 // poj3648 5 // 女2n男2n+1 6 #includeiostream 7 #includecstdio 8 #includecstring 9 #incl
  1 //https://blog.csdn.net/jarjingx/article/details/8521690
  2 //上面是讲解,下面是代码
  3 //https://www.e-learn.cn/content/qita/1061337
  4 //poj3648
  5 //女2n男2n+1
  6 #include<iostream>
  7 #include<cstdio>
  8 #include<cstring>
  9 #include<queue>
 10 using namespace std;
 11 const int N=1e5+6;
 12 struct edge{
 13     int to,nex;
 14 }e[N];
 15 edge e2[N];
 16 int h[N],h2[N],sta[N],col[N],blg[N],low[N],dfn[N],in[N],ops[N];
 17 bool insta[N];
 18 int n,m,cnt,cnt2,dfsnum,top;
 19 void add(int a,int b){
 20     e[++cnt]=(edge){b,h[a]};
 21     h[a]=cnt;
 22 }
 23 void add2(int a,int b){
 24     e2[++cnt2]=(edge){b,h2[a]};
 25     h2[a]=cnt2;
 26 }
 27 void tarjan(int x){
 28     low[x]=dfn[x]=++dfsnum;
 29     insta[x]=1;
 30     sta[++top]=x;
 31     for(int i=h[x];i;i=e[i].nex){
 32         int v=e[i].to;
 33         if(!dfn[v]){
 34             tarjan(v);
 35             low[x]=min(low[x],low[v]);
 36         }
 37         else if(insta[v]) low[x]=min(low[x],dfn[v]);
 38     }
 39     int cur;
 40     if(dfn[x]==low[x]){
 41         ++blg[0];
 42         do{
 43             cur=sta[top--];
 44             insta[cur]=0;
 45             blg[cur]=blg[0];
 46         }while(cur!=x);
 47     }
 48 }
 49 int main(){
 50     while(~scanf("%d%d",&n,&m)){
 51         //读入建图
 52         cnt=1;dfsnum=0;top=0,cnt2=1;
 53         memset(col,0,sizeof(col));
 54         memset(h,0,sizeof(h));
 55         memset(h2,0,sizeof(h2));
 56         memset(insta,0,sizeof(insta));
 57         memset(dfn,0,sizeof(dfn));
 58         memset(in,0,sizeof(in));
 59         if(n==0 && m==0) break;
 60         for(int i=1;i<=m;++i){
 61             int a,b;char c,d;
 62             scanf("%d%c %d%c",&a,&c,&b,&d);
 63             if(c==h && d==h){
 64                 add(2*a+1,2*b);
 65                 add(2*b+1,2*a);
 66             }
 67             if(c==h && d==w){
 68                 add(2*a+1,2*b+1);
 69                 add(2*b,2*a);
 70             }
 71             if(c==w && d==h){
 72                 add(2*a,2*b);
 73                 add(2*b+1,2*a+1);
 74             }
 75             if(c==w && d==w){
 76                 add(2*a,2*b+1);
 77                 add(2*b,2*a+1);
 78             }
 79         }
 80         add(0,1);
 81         //缩点
 82         for(int i=0; i < 2*n; ++i){
 83             if(!dfn[i]) tarjan(i);
 84         }
 85         bool fg=1;
 86         for(int i=0;i<2*n;i+=2){
 87             if(blg[i]==blg[i^1]){
 88                 puts("bad luck");
 89                 fg=0;
 90                 break;
 91             }
 92         }
 93         if(!fg) continue;
 94         //建反向图
 95         for(int u=0;u<2*n;++u){
 96             for(int i=h[u];i;i=e[i].nex){
 97                 int v=e[i].to;
 98                 int t1=blg[u],t2=blg[v];
 99                 if(t1!=t2){
100                     add2(t2,t1);
101                     ++in[t1];
102                 }
103             }
104         }
105         for(int i=0;i<2*n;i+=2){
106             ops[blg[i]]=blg[i^1];
107             ops[blg[i^1]]=blg[i];
108         }
109         //拓扑(染色)
110         queue<int> q;
111         for(int i=1;i<=blg[0];++i){
112             if(!in[i]) q.push(i);
113         }
114         while(!q.empty()){
115             int u=q.front();
116             q.pop();
117             if(!col[u]){
118                 col[u]=1;
119                 col[ops[u]]=-1;
120             }
121             for(int i=h2[u];i;i=e2[i].nex){
122                 int v=e2[i].to;
123                 --in[v];
124                 if(!in[v]) q.push(v);
125             }
126         }
127         //输出
128         for(int i=1;i<n; ++i){
129             if(col[blg[i<<1]]==-1) printf("%dw",i);
130             else printf("%dh",i);
131             if(i<n-1) printf(" ");
132             else printf("\n");
133         }
134     }
135     return 0;
136 }
网友评论