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