hdu 3062
2-SAT的入门题;
网上说这个算法最好的入门教材是:伍昱的《由对称性解2-SAT问题》的ppt和赵爽的论文《2-SAT 解法浅析》;
看了一下伍昱的ppt,很好理解!
而这道题相对ppt里面的例子来说更加简单;
代码:
1 #include<cstdio> 2 #include<stack> 3 #include<vector> 4 #include<algorithm> 5 #include<cstring> 6 #define maxn 2010 7 using namespace std; 8 9 vector<int>ve[maxn]; 10 stack<int>s; 11 int low[maxn],dfn[maxn],b[maxn],nncount,cnt; 12 bool instack[maxn]; 13 14 void tarjin(int u) 15 { 16 low[u]=dfn[u]=++nncount; 17 s.push(u); 18 instack[u]=1; 19 int l=ve[u].size(); 20 for(int i=0;i<l;i++) 21 { 22 int v=ve[u][i]; 23 if(!dfn[v]) 24 { 25 tarjin(v); 26 low[u]=min(low[u],low[v]); 27 } 28 else if(instack[v]) 29 low[u]=min(low[u],dfn[v]); 30 } 31 if(low[u]==dfn[u]) 32 { 33 cnt++; 34 int v; 35 do 36 { 37 v=s.top(); 38 s.pop(); 39 b[v]=cnt; 40 instack[v]=0; 41 }while(v!=u); 42 } 43 } 44 45 int main() 46 { 47 int n,m,x,y,u,v; 48 while(scanf("%d%d",&n,&m)!=EOF) 49 { 50 for(int i=0;i<2*n;i++) 51 ve[i].clear(); 52 memset(low,0,sizeof low); 53 memset(dfn,0,sizeof dfn); 54 memset(b,0,sizeof b); 55 nncount=cnt=0; 56 for(int i=0;i<m;i++) 57 { 58 scanf("%d%d%d%d",&x,&y,&u,&v); 59 ve[(x<<1)+u].push_back((y<<1|1)-v); 60 ve[(y<<1)+v].push_back((x<<1|1)-u); 61 } 62 bool flag=0; 63 for(int i=0;i<2*n;i++) 64 if(!dfn[i]) tarjin(i); 65 for(int i=0;i<n;i++) 66 if(b[i<<1]==b[i<<1|1]) {flag=1;break;} 67 if(flag) puts("NO"); 68 else puts("YES"); 69 } 70 return 0; 71 }