2-sat模板
Posted SummerSky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2-sat模板相关的知识,希望对你有一定的参考价值。
暴力:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<cstdlib> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 typedef long double ld; 11 typedef pair<int,int> pr; 12 const double pi=acos(-1); 13 #define rep(i,a,n) for(int i=a;i<=n;i++) 14 #define per(i,n,a) for(int i=n;i>=a;i--) 15 #define Rep(i,u) for(int i=head[u];i;i=Next[i]) 16 #define clr(a) memset(a,0,sizeof(a)) 17 #define pb push_back 18 #define mp make_pair 19 #define fi first 20 #define sc second 21 #define pq priority_queue 22 #define pqb priority_queue <int, vector<int>, less<int> > 23 #define pqs priority_queue <int, vector<int>, greater<int> > 24 #define vec vector 25 ld eps=1e-9; 26 ll pp=1000000007; 27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} 28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} 29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } 30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; } 31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; 32 ll read(){ ll ans=0; char last=‘ ‘,ch=getchar(); 33 while(ch<‘0‘ || ch>‘9‘)last=ch,ch=getchar(); 34 while(ch>=‘0‘ && ch<=‘9‘)ans=ans*10+ch-‘0‘,ch=getchar(); 35 if(last==‘-‘)ans=-ans; return ans; 36 } 37 const int N=16005; 38 const int M=50000; 39 int head[N],Next[M],v[M],ans[N],S[N],top,e,n,m; 40 void add(int x,int y){ v[++e]=y; Next[e]=head[x]; head[x]=e;} 41 int dfs(int x){ 42 if (ans[x]) return 1; 43 if (ans[x^1]) return 0; 44 ans[x]=1; S[++top]=x; 45 for (int i=head[x];i;i=Next[i]){ 46 if (!dfs(v[i])) return 0; 47 } 48 return 1; 49 } 50 int work(){ 51 for (int i=0;i<n+n;i+=2){ 52 if (ans[i] || ans[i^1]) continue; 53 top=0; 54 if (!dfs(i)){ 55 while (top) ans[S[top--]]=0; 56 if (!dfs(i^1)) { 57 while (top) ans[S[top--]]=0; 58 return 0; 59 } 60 } 61 } 62 return 1; 63 } 64 int main(){ 65 while (~scanf("%d%d",&n,&m)){ 66 e=0; 67 for (int i=0;i<n+n;i++) head[i]=0; 68 while (m--){ 69 int a=read(),b=read(); a--; b--; 70 add(a,b^1); add(b,a^1); 71 } 72 for (int i=0;i<n+n;i++) ans[i]=0; 73 if (!work()){ 74 puts("NIE"); 75 } else { 76 for (int i=0;i<n+n;i++) 77 if (ans[i]) printf("%d\n",i+1); 78 } 79 } 80 return 0; 81 }
2-sat:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<cstdlib> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 typedef long double ld; 11 typedef pair<int,int> pr; 12 const double pi=acos(-1); 13 #define rep(i,a,n) for(int i=a;i<=n;i++) 14 #define per(i,n,a) for(int i=n;i>=a;i--) 15 #define Rep(i,u) for(int i=head[u];i;i=Next[i]) 16 #define clr(a) memset(a,0,sizeof(a)) 17 #define pb push_back 18 #define mp make_pair 19 #define fi first 20 #define sc second 21 #define pq priority_queue 22 #define pqb priority_queue <int, vector<int>, less<int> > 23 #define pqs priority_queue <int, vector<int>, greater<int> > 24 #define vec vector 25 ld eps=1e-9; 26 ll pp=1000000007; 27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} 28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} 29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } 30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; } 31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; 32 ll read(){ ll ans=0; char last=‘ ‘,ch=getchar(); 33 while(ch<‘0‘ || ch>‘9‘)last=ch,ch=getchar(); 34 while(ch>=‘0‘ && ch<=‘9‘)ans=ans*10+ch-‘0‘,ch=getchar(); 35 if(last==‘-‘)ans=-ans; return ans; 36 } 37 const int N=16005; 38 const int M=50000; 39 int head[N],Next[M],v[M],head_[N],Next_[M],v_[M],dfn[N],Time,Stack[N],Ins[N],low[N],ans[N],S[N],top,e,n,m,num,belong[N],in[N],l[N]; 40 #include<queue> 41 queue<int> Q[2]; 42 void add(int x,int y){ v[++e]=y; Next[e]=head[x]; head[x]=e;} 43 void add_(int x,int y){ v_[++e]=y; Next_[e]=head_[x]; head_[x]=e;} 44 void Taj(int u){ 45 dfn[u]=low[u]=++Time; Stack[++top]=u; Ins[u]=1; 46 for (int i=head[u];i;i=Next[i]) 47 if (dfn[v[i]]==0){ 48 Taj(v[i]); 49 low[u]=min(low[u],low[v[i]]); 50 } else if (Ins[v[i]]) low[u]=min(low[u],dfn[v[i]]); 51 if (low[u]==dfn[u]){ 52 num++; 53 while (Stack[top]!=u) { 54 Ins[Stack[top]]=0; 55 belong[Stack[top]]=num; 56 top--; 57 } 58 Ins[Stack[top]]=0; 59 belong[Stack[top]]=num; 60 top--; 61 } 62 63 } 64 int pd(){ 65 for (int i=0;i<n+n;i+=2){ 66 if (belong[i+1]==belong[i]) return 1; 67 } 68 return 0; 69 } 70 void TopS(){ 71 for (int i=1;i<=num;i++) 72 if (!in[i]){ 73 Q[0].push(i); 74 } 75 int p=0; 76 while (!Q[p%2].empty()){ 77 while (!Q[p%2].empty()){ 78 int u=Q[p%2].front(); Q[p%2].pop(); if (ans[l[u]]==1) continue; ans[u]=1; 79 for (int i=head_[u];i;i=Next_[i]){ 80 in[v_[i]]--; 81 if (!in[v_[i]]) Q[(p+1)%2].push(v_[i]); 82 } 83 } 84 p++; 85 } 86 for (int i=0;i<n+n;i++) 87 if (ans[belong[i]]){ 88 printf("%d\n",i+1); 89 } 90 } 91 int main(){ 92 while (~scanf("%d%d",&n,&m)){ 93 e=0; 94 for (int i=0;i<n+n;i++) head[i]=0; 95 for (int i=0;i<n+n;i++) head_[i]=0; 96 while (m--){ 97 int a=read(),b=read(); a--; b--; 98 add(a,b^1); add(b,a^1); 99 } 100 top=0; num=0; Time=0; e=0; 101 memset(dfn,0,sizeof(dfn)); 102 memset(low,0,sizeof(low)); 103 memset(Ins,0,sizeof(Ins)); 104 memset(ans,0,sizeof(ans)); 105 memset(in,0,sizeof(in)); 106 for (int i=0;i<n+n;i++) 107 if (!dfn[i]) Taj(i); 108 for (int i=0;i<n+n;i++){ 109 for (int j=head[i];j;j=Next[j]){ 110 if (belong[i]!=belong[v[j]]){ 111 add_(belong[v[j]],belong[i]); in[belong[i]]++; 112 } 113 } 114 } 115 for (int i=0;i<n+n;i+=2){ 116 l[belong[i]]=belong[i+1]; 117 l[belong[i+1]]=belong[i]; 118 } 119 if (pd()){ 120 puts("NIE\n"); 121 } else TopS(); 122 } 123 return 0; 124 }
以上是关于2-sat模板的主要内容,如果未能解决你的问题,请参考以下文章