SAT算法

匿名 (未验证) 提交于 2019-12-03 00:10:02

今早用微云打的笔记...头大

我惊,这不是可爱的离散吗?!

手热来了一发模板题https://www.luogu.org/problem/P4782

 1 #include <bits/stdc++.h>  2 using namespace std;  3 const int N=1e6+5;  4 int n,m,a,b,fla,flb,cnt,head[N<<1];  5 int dfn[N<<1],low[N<<1],vis[N<<1],col[N<<1],scnt,idx;  6 stack<int> st;  7 struct edge{  8     int to,next;  9 }e[N<<1]; 10 inline void addedge(int a,int b) 11 { 12     e[++cnt]={b,head[a]}; 13     head[a]=cnt; 14 } 15 void tarjan(int u) 16 { 17     dfn[u]=low[u]=++idx;vis[u]=1; 18     st.push(u); 19     for(int i=head[u];i;i=e[i].next) 20     { 21         if(!dfn[e[i].to]) tarjan(e[i].to),low[u]=min(low[u],low[e[i].to]); 22         else if(vis[e[i].to]) low[u]=min(low[u],dfn[e[i].to]); 23     } 24     if(low[u]==dfn[u]) 25     { 26         scnt++;int v=-1; 27         while(v!=u) 28         { 29             v=st.top();st.pop(); 30             col[v]=scnt,vis[v]=0; 31         } 32     } 33 } 34 int main() 35 { 36     for(scanf("%d%d",&n,&m);m--;){ 37         scanf("%d%d%d%d",&a,&fla,&b,&flb); 38         int aa=fla^1,bb=flb^1; 39         addedge(a+aa*n,b+flb*n); 40         addedge(b+bb*n,a+fla*n); 41     } 42     for(int i=1;i<=2*n;i++) 43         if(!dfn[i]) tarjan(i); 44     for(int i=1;i<=n;i++) 45         if(col[i]==col[n+i]) return puts("IMPOSSIBLE")&0; 46     puts("POSSIBLE"); 47     for(int i=1;i<=n;i++) printf("%d%c",col[i]>col[n+i],i==n?'\n':' '); 48 }
View Code

然后又很智障得磕了http://acm.hdu.edu.cn/showproblem.php?pid=3062

因为初始化和下标问题还WA了半天,就简单YES、NO的我都能PE,自闭半小时

 1 #include <bits/stdc++.h>  2 using namespace std;  3 const int N=1005;  4 int n,m,a,b,fla,flb,cnt,scnt,idx;  5 int head[N<<1],dfn[N<<1],low[N<<1],vis[N<<1],col[N<<1];  6 stack<int> st;  7 struct edge{  8     int to,next;  9 }e[N*N]; 10 void init() 11 { 12     memset(head,-1,sizeof(head)); 13     memset(dfn,0,sizeof(dfn)); 14     memset(vis,0,sizeof(vis)); 15     memset(low,0,sizeof(low)); 16     cnt=idx=scnt=0; 17 } 18 inline void addedge(int a,int b) 19 { 20     e[cnt]={b,head[a]}; 21     head[a]=cnt++; 22 } 23 void tarjan(int u) 24 { 25     dfn[u]=low[u]=++idx;vis[u]=1; 26     st.push(u); 27     for(int i=head[u];i!=-1;i=e[i].next) 28     { 29         if(!dfn[e[i].to]) tarjan(e[i].to),low[u]=min(low[u],low[e[i].to]); 30         else if(vis[e[i].to]) low[u]=min(low[u],dfn[e[i].to]); 31     } 32     if(low[u]==dfn[u]) 33     { 34         scnt++; 35         int v; 36         do{ 37             v=st.top();st.pop(); 38             col[v]=scnt,vis[v]=0; 39         }while(u!=v); 40     } 41 } 42 int main() 43 { 44     while(~scanf("%d",&n)) 45     { 46         scanf("%d",&m); 47         init(); 48         while(m--) 49         { 50             scanf("%d%d%d%d",&a,&b,&fla,&flb); 51             a=(a<<1)+fla; 52             b=(b<<1)+flb; 53             addedge(a,b^1); 54             addedge(b,a^1); 55         } 56         for(int i=0;i<2*n;i++) 57             if(!dfn[i]) tarjan(i); 58         int flag=0; 59         for(int i=0;i<2*n;i+=2) 60             if(col[i]==col[i^1]){puts("NO");flag=1;break;} 61         if(!flag) puts("YES"); 62     } 63 }
View Code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!