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 }
View Code

 

posted @ 2013-09-05 15:37  Yours1103  阅读(186)  评论(0编辑  收藏  举报