HDU 1814 Peaceful Commission (2-SAT按字典序输出方案)

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\n",i+1);
166         else printf("%d\n",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 }
View Code

 

posted @ 2013-11-01 09:32  xysmlx  阅读(285)  评论(0编辑  收藏  举报