Poj--2296(2-SAT,二分)

2014-10-19 13:55:03

思路:典型的2分+2-SAT,给题目数据范围跪了,之前RE到寺,我开到1000才过QAQ。

  首先二分边长d 。

  建图:分类讨论,如果两点间x坐标绝对值差>=d则不用建边,如果x坐标绝对值<d,则分:(1)y坐标绝对值差>=2d不用建边(2)y坐标绝对值差<2d且>=d(3)y坐标绝对值差<d且>0(4)y绝对值差 == 0 (这种情况一定要考虑到。)

  1 /*************************************************************************
  2     > File Name: 2296.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com
  5     > Created Time: Sat 18 Oct 2014 06:24:02 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 = 1000;
 27 
 28 int n,m,t;
 29 int x[maxn],y[maxn];
 30 int low[maxn],dfn[maxn],sc[maxn],scnt,tot;
 31 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt;
 32 stack<int> S;
 33 
 34 void Add_edge(int u,int v){
 35     next[++ecnt] = first[u];
 36     ver[ecnt] = v;
 37     first[u] = ecnt;
 38 }
 39 
 40 void Dfs(int p){
 41     dfn[p] = low[p] = ++tot;
 42     S.push(p);
 43     for(int i = first[p]; i != -1; i = next[i]){
 44         int v = ver[i];
 45         if(!dfn[v]){
 46             Dfs(v);
 47             low[p] = min(low[p],low[v]);
 48         }
 49         else if(!sc[v]){
 50             low[p] = min(low[p],dfn[v]);
 51         }
 52     }
 53     if(low[p] == dfn[p]){
 54         ++scnt;
 55         while(1){
 56             int tem = S.top();
 57             S.pop();
 58             sc[tem] = scnt;
 59             if(tem == p) break;
 60         }
 61     }
 62 }
 63 
 64 void Tarjan(){
 65     memset(low,0,sizeof(low));
 66     memset(dfn,0,sizeof(dfn));
 67     memset(sc,0,sizeof(sc));
 68     while(!S.empty()) S.pop();
 69     scnt = tot = 0;
 70     for(int i = 0; i < 2 * m; ++i)
 71         if(!dfn[i]) Dfs(i);
 72 }
 73 
 74 void Init(){
 75     memset(first,-1,sizeof(first));
 76 }
 77 
 78 bool Solve(int val){
 79     //Build graph
 80     Init();
 81     int dx,dy;
 82     for(int i = 0; i < m; ++i){
 83         for(int j = i + 1; j < m; ++j){
 84             dx = abs(x[i] - x[j]);
 85             dy = abs(y[i] - y[j]);
 86             if(dx < val){
 87                 if(dy < 2 * val){
 88                     if(dy >= val){
 89                         if(y[i] > y[j]){
 90                             Add_edge(i * 2 + 1,j * 2 + 1);
 91                             Add_edge(j * 2,i * 2);
 92                         }
 93                         else{
 94                             Add_edge(j * 2 + 1,i * 2+ 1);
 95                             Add_edge(i * 2,j * 2);
 96                         }
 97                     }
 98                     else if(dy > 0){
 99                         if(y[i] > y[j]){
100                             Add_edge(i * 2,j * 2 + 1);
101                             Add_edge(i * 2 + 1,i * 2);
102                             Add_edge(j * 2 + 1,i * 2);
103                             Add_edge(j * 2,j * 2 + 1);
104                         }
105                         else{
106                             Add_edge(j * 2,i * 2 + 1);
107                             Add_edge(j * 2 + 1,j * 2);
108                             Add_edge(i * 2 + 1,j * 2);
109                             Add_edge(i * 2,i * 2 + 1);
110                         }
111                     }
112                     else{
113                         Add_edge(i * 2,j * 2 + 1);
114                         Add_edge(j * 2 + 1,i * 2);
115                         Add_edge(i * 2 + 1,j * 2);
116                         Add_edge(j * 2,i * 2 + 1);
117                     }
118                 }
119             }
120         }
121     }
122     Tarjan();
123     for(int i = 0; i < 2 * m; i += 2){
124         if(sc[i] == sc[i + 1])
125             return false;
126     }
127     return true;
128 }
129 
130 int main(){
131     scanf("%d",&t);
132     while(t--){
133         scanf("%d",&m);
134         for(int i = 0; i < m; ++i)
135             scanf("%d%d",x + i,y + i);
136         int mid,l = 0,r = 20001,ans;
137         while(l < r){
138             mid = l + (r - l) / 2;
139             if(Solve(mid)){
140                 ans = mid;
141                 l = mid + 1;
142             }
143             else
144                 r = mid;
145         }
146         printf("%d\n",ans);
147     }
148     return 0;
149 }

 

posted @ 2014-10-19 14:04  Naturain  阅读(108)  评论(0编辑  收藏  举报