const double EPS = 1e-9; const int MAXV = 100010; struct TwoSAT { int n; vector<int> G[MAXV*2]; bool mark[MAXV*2]; int S[MAXV*2], c; void init(int n) { this->n = n; for (int i = 0; i < n*2; i++) G[i].clear(); memset(mark, 0, sizeof(mark)); } bool dfs(int x) { if (mark[x^1]) return false; if (mark[x]) return true; mark[x] = true; S[c++] = x; for (int i = 0; i < G[x].size(); i++) if (!dfs(G[x][i])) return false; return true; } // x = xval or y = yval void add_clause(int x, int xval, int y, int yval) { x = x * 2 + xval; y = y * 2 + yval; G[x^1].push_back(y); G[y^1].push_back(x); } bool solve() { for(int i = 0; i < n*2; i += 2) if(!mark[i] && !mark[i+1]) { c = 0; if(!dfs(i)) { while(c > 0) mark[S[--c]] = false; if(!dfs(i+1)) return false; } } return true; } } tst; int n, m; struct Point { double x, y, z; inline void read() { scanf("%lf%lf%lf", &x, &y, &z); } } ipt[MAXN][2]; inline double dis(Point pa, Point pb) { return sqrt(sqr(pa.x - pb.x) + sqr(pa.y - pb.y) + sqr(pa.z - pb.z)); } bool check(double Min) { tst.init(n); REP(i, n) FF(j, i + 1, n) { REP(ii, 2) REP(jj, 2) { double d = dis(ipt[i][ii], ipt[j][jj]); if (d < Min) { tst.add_clause(i, ii ^ 1, j, jj ^ 1); } } } return tst.solve(); } int main() { while (~RI(n)) { REP(i, n) REP(j, 2) ipt[i][j].read(); double l = 0, r = 1e20, m; while (l + EPS < r) { m = (l + r) / 2; if (check(m * 2)) l = m; else r = m; } printf("%.3f\n", (int)(r * 1000) / 1000.0); } return 0; }
原文:http://blog.csdn.net/wty__/article/details/38125631