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 }
源代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }