POJ 3905 2-SAT

View Code
  1 //Result:wizmann    3905    Accepted    16516K    1985MS    G++    2170B    2012-10-08 16:19:01
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <stack>
  8 
  9 using namespace std;
 10 
 11 #define print(x) cout<<x<<endl
 12 #define input(x) cin>>x
 13 #define SIZE 2048
 14 #define EDGE 4096000
 15 
 16 struct node
 17 {
 18     int val,next;
 19     node(){}
 20     node(int ival,int inext)
 21     {
 22         val=ival;
 23         next=inext;
 24     }
 25 };
 26 
 27 int n,m;
 28 int head[SIZE];
 29 node g[EDGE];
 30 int ind;
 31 
 32 char instack[SIZE];
 33 stack<int> st;
 34 int dfn[SIZE],scc[SIZE],num[SIZE],low[SIZE];
 35 int sccnr,nr;
 36 
 37 void init()
 38 {
 39     ind=0;
 40     memset(head,-1,sizeof(head));
 41     memset(instack,0,sizeof(instack));
 42     memset(scc,0,sizeof(scc));
 43     memset(num,0,sizeof(num));
 44     memset(low,0,sizeof(low));
 45     memset(dfn,0,sizeof(dfn));
 46     st=stack<int>();
 47     nr=1;sccnr=0;
 48 }
 49 
 50 void tarjan(int pos)
 51 {
 52     low[pos]=dfn[pos]=nr++;
 53     st.push(pos);
 54     instack[pos]=1;
 55 
 56     for(int i=head[pos];i!=-1;i=g[i].next)
 57     {
 58         int j=g[i].val;
 59         if(!dfn[j])
 60         {
 61             tarjan(j);
 62             low[pos]=min(low[pos],low[j]);
 63         }
 64         else if(instack[j])
 65         {
 66             low[pos]=min(low[pos],dfn[j]);
 67         }
 68     }
 69 
 70     if(dfn[pos]==low[pos])
 71     {
 72         sccnr++;
 73         while(1)
 74         {
 75             int t=st.top();
 76             instack[t]=0;
 77             st.pop();
 78             scc[t]=sccnr;
 79             num[sccnr]++;
 80             if(t==pos) break;
 81         }
 82     }
 83 }
 84 
 85 inline void addEdge(int a,int b)
 86 {
 87     g[ind]=node(b,head[a]);
 88     head[a]=ind++;
 89 }
 90 
 91 bool zSat()
 92 {
 93     for(int i=0;i<n*2;i++)
 94     {
 95         if(!dfn[i]) tarjan(i);
 96     }
 97     for(int i=0;i<n;i++)
 98     {
 99         if(scc[i]==scc[i+n]) return false;
100     }
101     return true;
102 }
103 
104 int main()
105 {
106     freopen("input.txt","r",stdin);
107     int a,b;
108     while(input(n>>m))
109     {
110         init();
111         for(int i=0;i<m;i++)
112         {
113             scanf("%d%d",&a,&b);
114             if(a>0 && b>0)  // a or b => (a+n,b),(b+n,a)
115             {
116                 a=abs(a);
117                 b=abs(b);
118                 --a;--b;
119 
120                 addEdge(a+n,b);
121                 addEdge(b+n,a);
122             }
123             else if(a<0 && b<0) // not a or not b =>(a,b+n),(b,a+n)
124             {
125                 a=abs(a);
126                 b=abs(b);
127                 --a;--b;
128 
129                 addEdge(a,b+n);
130                 addEdge(b,a+n);
131             }
132             else if(a>0 && b<0) // a or not b =>(a+n,b+n),(b,a)
133             {
134                 a=abs(a);
135                 b=abs(b);
136                 --a;--b;
137 
138                 addEdge(a+n,b+n);
139                 addEdge(b,a);
140             }
141             else if(a<0 && b>0) // not a or b =>(a,b),(b+n,a+n)
142             {
143                 a=abs(a);
144                 b=abs(b);
145                 --a;--b;
146 
147                 addEdge(a,b);
148                 addEdge(b+n,a+n);
149             }
150         }
151         if(zSat()) puts("1");
152         else puts("0");
153     }
154     return 0;
155 }

posted on 2012-10-13 14:04  Wizmann  阅读(216)  评论(0编辑  收藏  举报

导航