POJ 3207 Ikki's Story IV - Panda's Trick (2-SAT可行性判定)

http://poj.org/problem?id=3207

两条边不能相交->两条边仅能存1->两条边XOR=1

明显的2-SAT

如果扫描到两条边可能相交就按XOR=1的规则加边,然后用2-SAT判可行性即可

可能相交条件:

1 bool check(int i,int j)
2 {
3     return (node[i].x<node[j].x&&node[j].x<node[i].y&&node[i].y<node[j].y)||(node[j].x<node[i].x&&node[i].x<node[j].y&&node[j].y<node[i].y);
4 }

源代码:

  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=1010;
 23 const int maxm=510;
 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[1010];
 41     bool mark[1010];
 42     int S[1010], 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 struct Node
140 {
141     int x,y;
142 }node[maxm];
143 int n,m;
144 void init()
145 {
146     //
147 }
148 void input()
149 {
150     if(scanf("%d%d",&n,&m)==EOF) exit(0);
151     for(int i=0;i<m;i++)
152     {
153         int x,y;
154         scanf("%d%d",&x,&y);
155         if(x>y) swap(x,y);
156         node[i].x=x;
157         node[i].y=y;
158     }
159 }
160 bool check(int i,int j)
161 {
162     return (node[i].x<node[j].x&&node[j].x<node[i].y&&node[i].y<node[j].y)||(node[j].x<node[i].x&&node[i].x<node[j].y&&node[j].y<node[i].y);
163 }
164 void solve()
165 {
166     sat.init(m);
167     for(int i=0;i<m;i++)
168     {
169         for(int j=i+1;j<m;j++)
170         {
171             if(check(i,j))
172             {
173                 sat.add_xor_one(2*i,2*j);
174             }
175         }
176     }
177     if(sat.solve()) puts("panda is telling the truth...");
178     else puts("the evil panda is lying again");
179 }
180 void output()
181 {
182     //
183 }
184 int main()
185 {
186 //    std::ios_base::sync_with_stdio(false);
187 //    freopen("in.cpp","r",stdin);
188     while(1)
189     {
190         init();
191         input();
192         solve();
193         output();
194     }
195     return 0;
196 }
View Code

 

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