2014-team3/code/closest_pair
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0; i<int(n); i++)
#define pb push_back
#define mp make_pair
#define X first
#define Y second
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
double eps=1e-9;
struct CMP;
typedef double TData;
const int nDim=3;
template <class T>
T sqr(T x){return x*x;}
struct Pt{
TData x[nDim];
int id;
friend CMP;
friend TData dis(Pt a, Pt b){
TData res=0;
for(int i=0; i<nDim; ++i)
res+=sqr(a.x[i]-b.x[i]);
return sqrt(res);
}
};
bool cmp_dis_accurately(pii a, pii b){
return dis(pts[a.X], pts[a.Y])<dis(pts[b.X], pts[b.Y]);
}
struct CMP{
int dim;
bool operator()(Pt l, Pt r) const {
return l.x[dim] < r.x[dim];
}
} cmp;
TData min_dis=1e9; //This number should be large enough
pii best_pair=mp(-1,-1); //stores the closest pair
void take_best(Pt a, Pt b){
if(best_pair.X==-1 || cmp_dis_accurately(mp(a.id, b.id), best_pair)){
best_pair=mp(a.id, b.id);
min_dis=dis(a, b)+eps;
}
}
//find the closest pair in v[l, r)
//make sure v is sorted by dimension[0] in ascending order before calling closest_pair()
void closest_pair(vector<Pt> &v, int l, int r, int dim=0){
if(dim+1==nDim){
int z=nDim-1;
REP(i, v.size()){
for(int j=1; i+j<v.size() && v[j].x[z]-v[i].x[z]<=min_dis; ++j)
take_best(v[i], v[i+j]);
}
return;
}
if(r-l<=3){ //for higher dimensions r-l<=100 is much faster
for(int i=l+1; i<r; ++i)
for(int j=l; j<i; ++j)
take_best(v[i], v[j]);
return;
}
int m=(l+r)/2;
closest_pair(v, l, m, dim);
closest_pair(v, m, r, dim);
vector<Pt> vtmp;
REP(i,v.size())if(abs(v[i].x[dim]-v[m].x[dim])<=min_dis)
vtmp.pb(v[i]);
cmp.dim=dim+1;
sort(vtmp.begin(), vtmp.end(), cmp);
closest_pair(vtmp, 0, vtmp.size(), dim+1);
}
}}}
#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0; i<int(n); i++)
#define pb push_back
#define mp make_pair
#define X first
#define Y second
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
double eps=1e-9;
struct CMP;
typedef double TData;
const int nDim=3;
template <class T>
T sqr(T x){return x*x;}
struct Pt{
TData x[nDim];
int id;
friend CMP;
friend TData dis(Pt a, Pt b){
TData res=0;
for(int i=0; i<nDim; ++i)
res+=sqr(a.x[i]-b.x[i]);
return sqrt(res);
}
};
bool cmp_dis_accurately(pii a, pii b){
return dis(pts[a.X], pts[a.Y])<dis(pts[b.X], pts[b.Y]);
}
struct CMP{
int dim;
bool operator()(Pt l, Pt r) const {
return l.x[dim] < r.x[dim];
}
} cmp;
TData min_dis=1e9; //This number should be large enough
pii best_pair=mp(-1,-1); //stores the closest pair
void take_best(Pt a, Pt b){
if(best_pair.X==-1 || cmp_dis_accurately(mp(a.id, b.id), best_pair)){
best_pair=mp(a.id, b.id);
min_dis=dis(a, b)+eps;
}
}
//find the closest pair in v[l, r)
//make sure v is sorted by dimension[0] in ascending order before calling closest_pair()
void closest_pair(vector<Pt> &v, int l, int r, int dim=0){
if(dim+1==nDim){
int z=nDim-1;
REP(i, v.size()){
for(int j=1; i+j<v.size() && v[j].x[z]-v[i].x[z]<=min_dis; ++j)
take_best(v[i], v[i+j]);
}
return;
}
if(r-l<=3){ //for higher dimensions r-l<=100 is much faster
for(int i=l+1; i<r; ++i)
for(int j=l; j<i; ++j)
take_best(v[i], v[j]);
return;
}
int m=(l+r)/2;
closest_pair(v, l, m, dim);
closest_pair(v, m, r, dim);
vector<Pt> vtmp;
REP(i,v.size())if(abs(v[i].x[dim]-v[m].x[dim])<=min_dis)
vtmp.pb(v[i]);
cmp.dim=dim+1;
sort(vtmp.begin(), vtmp.end(), cmp);
closest_pair(vtmp, 0, vtmp.size(), dim+1);
}