首页 > 代码库 > ZOJ 3717 Balloon (二分+2-sat)
ZOJ 3717 Balloon (二分+2-sat)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3717
2-sat版题
对半径R进行二分,将二分得到的R用2-sat判,如果2R<dis(i,j),则建边add_and_zero(i,j),然后看是否有解
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 = 410; 23 const int maxm = 410 * 410; 24 const int inf = 0x3f3f3f3f; 25 const LL inf64 = 0x3f3f3f3f3f3f3f3fLL; 26 const double INF = 1e30; 27 const double eps = 1e-8; 28 const int P[4] = {0, 0, -1, 1}; 29 const int Q[4] = {1, -1, 0, 0}; 30 const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1}; 31 const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1}; 32 /** 33 *2-SAT模板: 按字典序排列结果 34 *输入:按照法则添加边(参数为2*i或者2*i+1) 35 *运行:先init(n),再add(),再solve() 36 *注意:add(2*i,2*j)才行 37 *输出:vis[](1表示选中),solve()(是否有解) 38 */ 39 // const int maxn = 0; 40 // const int maxm = 0; 41 struct Edge 42 { 43 int u, v; 44 int next; 45 }; 46 struct TwoSAT 47 { 48 int n, en; 49 Edge edge[maxm]; 50 int head[maxn]; 51 int vis[maxn], S[maxn]; 52 int cnt; 53 54 void init(int _n = 0) 55 { 56 n = _n; 57 memset(head, -1, sizeof(head)); 58 en = 0; 59 memset(vis, 0, sizeof(vis)); 60 } 61 62 void addse(int u, int v) 63 { 64 edge[en].u = u; 65 edge[en].v = v; 66 edge[en].next = head[u]; 67 head[u] = en++; 68 } 69 70 bool dfs(int u) 71 { 72 if (vis[u ^ 1])return 0; 73 if (vis[u])return 1; 74 vis[u] = 1; 75 S[cnt++] = u; 76 for (int i = head[u]; i != -1; i = edge[i].next) 77 { 78 if (!dfs(edge[i].v))return 0; 79 } 80 return 1; 81 } 82 83 bool solve() 84 { 85 for (int i = 0; i < 2 * n; i += 2) 86 { 87 if (vis[i] || vis[i ^ 1])continue; 88 cnt = 0; 89 if (!dfs(i)) 90 { 91 while (cnt)vis[S[--cnt]] = 0; 92 if (!dfs(i ^ 1))return 0; 93 } 94 } 95 return 1; 96 } 97 98 /// x AND y = 1 99 void add_and_one(int x, int y)100 {101 addse(x ^ 1, y);102 addse(y ^ 1, x);103 addse(x, y);104 addse(y ^ 1, x ^ 1);105 addse(y, x);106 addse(x ^ 1, y ^ 1);107 }108 109 /// x AND y = 0110 void add_and_zero(int x, int y)111 {112 addse(x, y ^ 1);113 addse(y, x ^ 1);114 }115 116 /// x OR y = 1117 void add_or_one(int x, int y)118 {119 addse(x ^ 1, y);120 addse(y ^ 1, x);121 }122 123 /// x OR y = 0124 void add_or_zero(int x, int y)125 {126 addse(x, y ^ 1);127 addse(y, x ^ 1);128 addse(x, y);129 addse(y ^ 1, x ^ 1);130 addse(x ^ 1, y ^ 1);131 addse(y, x);132 }133 134 /// x XOR y = 1135 void add_xor_one(int x, int y)136 {137 addse(x ^ 1, y);138 addse(y ^ 1, x);139 addse(x, y ^ 1);140 addse(y, x ^ 1);141 }142 143 /// x XOR y = 0144 void add_xor_zero(int x, int y)145 {146 addse(x ^ 1, y ^ 1);147 addse(y, x);148 addse(x, y);149 addse(y ^ 1, x ^ 1);150 }151 152 /// x -> y153 void add_to(int x, int y)154 {155 addse(x, y);156 addse(y ^ 1, x ^ 1);157 }158 } sat;159 160 int n;161 struct Node162 {163 int x, y, z;164 Node(int _x = -1, int _y = -1, int _z = -1): x(_x), y(_y), z(_z) {}165 } node[maxn];166 void init()167 {168 //169 }170 void input()171 {172 for (int i = 0; i < 2 * n; i++)173 {174 scanf("%d%d%d", &node[i].x, &node[i].y, &node[i].z);175 }176 }177 void debug()178 {179 //180 }181 double dis(int a, int b)182 {183 return sqrt((node[a].x - node[b].x) * (node[a].x - node[b].x) + (node[a].y - node[b].y) * (node[a].y - node[b].y) + (node[a].z - node[b].z) * (node[a].z - node[b].z));184 }185 bool test(double r)186 {187 sat.init(n);188 // for (int i = 0; i < n; i++)189 // {190 // sat.add_xor_one(2 * i, 2 * i + 1);191 // }192 for (int i = 0; i < 2 * n; i++)193 {194 for (int j = i + 1; j < 2 * n; j++)195 {196 if (2 * r > dis(i, j))197 sat.add_and_zero(i, j);198 }199 }200 return sat.solve();201 }202 void solve()203 {204 double L = 0, R = 20000;205 while (L + eps < R)206 {207 double M = (L + R) / 2;208 if (test(M)) L = M;209 else R = M;210 }211 printf("%f\n", L);212 }213 void output()214 {215 //216 }217 int main()218 {219 // std::ios_base::sync_with_stdio(false);220 // #ifndef ONLINE_JUDGE221 // freopen("in.cpp", "r", stdin);222 // #endif223 224 while (~scanf("%d", &n))225 {226 init();227 input();228 solve();229 output();230 }231 return 0;232 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。