2014-10-15 23:46:02
思路:2-SAT 启蒙题,很裸很粗暴。直接敲,基本思路:把每个家庭的妻子和丈夫各看做一个点,链前向星建图,一条关系建两条边,然后循环一遍Dfs所有点,每个点Dfs两次(分别指派这个点为真和假),只要发现某次Dfs能成功遍历完一圈那么说明这个真值指派是可行的,即可退出。如果两次Dfs均失败,那么2-sat图不可建。
1 /************************************************************************* 2 > File Name: 3062.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 15 Oct 2014 11:22:36 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 2010; 27 28 int n,m,cnt; 29 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt; 30 int S[maxn]; 31 bool mark[maxn]; 32 33 void Init(){ 34 memset(first,-1,sizeof(first)); 35 memset(mark,false,sizeof(mark)); 36 ecnt = 0; 37 cnt = 0; 38 } 39 40 void Add_edge(int u,int v){ 41 next[++ecnt] = first[u]; 42 ver[ecnt] = v; 43 first[u] = ecnt; 44 } 45 46 bool Dfs(int p){ 47 if(mark[p ^ 1]) return false; 48 if(mark[p]) return true; 49 mark[p] = true; //标记真值 50 S[cnt++] = p; //入队 51 for(int i = first[p]; i != -1; i = next[i]){ 52 int v = ver[i]; 53 if(!Dfs(v)) return false; 54 } 55 return true; 56 } 57 58 bool Two_sat(){ 59 int top = 2 * n; 60 for(int i = 0; i < top; i += 2){ 61 if(!mark[i] && !mark[i + 1]){ 62 if(!Dfs(i)){ 63 while(cnt > 0) mark[S[--cnt]] = false; 64 if(!Dfs(i + 1)) return false; 65 } 66 } 67 } 68 return true; 69 } 70 71 int main(){ 72 int a1,a2,c1,c2; 73 while(scanf("%d%d",&n,&m) != EOF){ 74 Init(); 75 for(int i = 0; i < m; ++i){ 76 scanf("%d%d%d%d",&a1,&a2,&c1,&c2); 77 int u,v; 78 u = a1 * 2 + c1; 79 v = a2 * 2 + c2; 80 Add_edge(u ^ 1,v); 81 Add_edge(v ^ 1,u); 82 } 83 if(Two_sat()) printf("YES\n"); 84 else printf("NO\n"); 85 } 86 return 0; 87 }