http://acm.hdu.edu.cn/showproblem.php?pid=1814
裸的2-SAT版题(模板得到的方案是按字典序得到的)(调试调到死。。。)
直接按照输入按AND=1的规则加边,然后跑2-SAT输出即可
2-SAT原理详见kuangbin大神的博客:http://www.cnblogs.com/kuangbin/archive/2012/10/05/2712429.html
1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<iostream> 4 #include<cstring> 5 #include<string> 6 #include<cmath> 7 #include<set> 8 #include<list> 9 #include<map> 10 #include<iterator> 11 #include<cstdlib> 12 #include<vector> 13 #include<queue> 14 #include<stack> 15 #include<algorithm> 16 #include<functional> 17 using namespace std; 18 typedef long long LL; 19 #define ROUND(x) round(x) 20 #define FLOOR(x) floor(x) 21 #define CEIL(x) ceil(x) 22 const int maxn=20010; 23 const int maxm=0; 24 const int inf=0x3f3f3f3f; 25 const LL inf64=0x3f3f3f3f3f3f3f3fLL; 26 const double INF=1e30; 27 const double eps=1e-6; 28 29 /** 30 *2-SAT模板,Modified Edition of LRJ 31 *输入:按照法则添加边(参数为2*i或者2*i+1) 32 *运行:先init(n),再add(),再solve() 33 *注意:add(2*i,2*j)才行 34 *输出:mark[](1表示选中),solve()(是否有解) 35 */ 36 //const int maxn = 0; 37 struct TwoSAT 38 { 39 int n; 40 vector<int> G[maxn*2]; 41 bool mark[maxn*2]; 42 int S[maxn*2], c; 43 44 bool dfs(int x) 45 { 46 if (mark[x^1]) return false; 47 if (mark[x]) return true; 48 mark[x] = true; 49 S[c++] = x; 50 for (int i = 0; i < G[x].size(); i++) 51 if (!dfs(G[x][i])) return false; 52 return true; 53 } 54 55 void init(int n) 56 { 57 this->n = n; 58 for (int i = 0; i < n*2; i++) G[i].clear(); 59 memset(mark, 0, sizeof(mark)); 60 } 61 62 /// x AND y = 1 63 void add_and_one(int x,int y) 64 { 65 G[x^1].push_back(y); 66 G[y^1].push_back(x); 67 G[x].push_back(y); 68 G[y^1].push_back(x^1); 69 G[y].push_back(x); 70 G[x^1].push_back(y^1); 71 } 72 73 /// x AND y = 0 74 void add_and_zero(int x,int y) 75 { 76 G[x].push_back(y^1); 77 G[y].push_back(x^1); 78 } 79 80 /// x OR y = 1 81 void add_or_one(int x,int y) 82 { 83 G[x^1].push_back(y); 84 G[y^1].push_back(x); 85 } 86 87 /// x OR y = 0 88 void add_or_zero(int x,int y) 89 { 90 G[x].push_back(y^1); 91 G[y].push_back(x^1); 92 G[x].push_back(y); 93 G[y^1].push_back(x^1); 94 G[x^1].push_back(y^1); 95 G[y].push_back(x); 96 } 97 98 /// x XOR y = 1 99 void add_xor_one(int x,int y) 100 { 101 G[x^1].push_back(y); 102 G[y^1].push_back(x); 103 G[x].push_back(y^1); 104 G[y].push_back(x^1); 105 } 106 107 /// x XOR y = 0 108 void add_xor_zero(int x,int y) 109 { 110 G[x^1].push_back(y^1); 111 G[y].push_back(x); 112 G[x].push_back(y); 113 G[y^1].push_back(x^1); 114 } 115 116 /// x -> y 117 void add_to(int x,int y) 118 { 119 G[x].push_back(y); 120 G[y^1].push_back(x^1); 121 } 122 123 bool solve() 124 { 125 for(int i = 0; i < n*2; i += 2) 126 if(!mark[i] && !mark[i+1]) 127 { 128 c = 0; 129 if(!dfs(i)) 130 { 131 while(c > 0) mark[S[--c]] = false; 132 if(!dfs(i+1)) return false; 133 } 134 } 135 return true; 136 } 137 }sat; 138 139 int n,m; 140 void init() 141 { 142 // 143 } 144 void input() 145 { 146 if(scanf("%d%d",&n,&m)==EOF) exit(0); 147 sat.init(2*n); 148 for(int i=0;i<m;i++) 149 { 150 int p,q; 151 scanf("%d%d",&p,&q); 152 p--,q--; 153 sat.add_and_zero(p,q); 154 } 155 } 156 void solve() 157 { 158 if(!sat.solve()) 159 { 160 puts("NIE"); 161 return; 162 } 163 for(int i=0;i<2*n;i+=2) 164 { 165 if(sat.mark[i]) printf("%d ",i+1); 166 else printf("%d ",i+2); 167 } 168 } 169 void output() 170 { 171 // 172 } 173 int main() 174 { 175 // std::ios_base::sync_with_stdio(false); 176 // freopen("in.cpp","r",stdin); 177 while(1) 178 { 179 init(); 180 input(); 181 solve(); 182 output(); 183 } 184 return 0; 185 }