GCJ2009B&JZOJ 4033 Min Perimeter

Posted rrsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCJ2009B&JZOJ 4033 Min Perimeter相关的知识,希望对你有一定的参考价值。

SOL:

 我们参考最近点对的做法,分治加当前最优解剪枝。

#pragma GCC optimize("-Ofast")
#include<bits/stdc++.h>
using namespace std;
#define max(a,b) ((a)<(b)?(b):(a))
#define min(a,b) ((a)<(b)?(a):(b))
#define fo(i,j,k) for (int i=(j);i<=(k);i++)
#define fd(i,j,k) for (int i=(j);i>=(k);i--)
#define fe(i,j) for (int j=head[i];j!=-1;j=mp[j].next)
#define fuck printf("666"
);
#define scan freopen("in.txt","r",stdin)
#define print freopen("out.txt","w",stdout)
const double inf=1e+20;
const int bil=1e+9;
struct P
{
  int x,y;
}px[100001];
int n;
vector<P> py;
inline char nc()
{
  static char buf[100000],*p1=buf,*p2=buf;
  if (p1==p2)
  {
    p2=(p1=buf)+fread(buf,1,100000,stdin);
    if (p1==p2) return EOF;
  }
  return *p1++;
}
inline void read(int &x)
{
  char c=nc();int b=1;
  for (;c<0||c>9;c=nc()) if (c==-) b=-1;
  for (x=0;c>=0&&c<=9;x=x*10+c-0,c=nc());
  x=x*b;
}
inline void read(long long &x)
{
  char c=nc();int b=1;
  for (;c<0||c>9;c=nc()) if (c==-) b=-1;
  for (x=0;c>=0&&c<=9;x=x*10+c-0,c=nc());
  x=x*b;
}
inline bool cmpx(const P& a,const P& b)
{
  if (a.x!=b.x) return a.x<b.x;
  return a.y<b.y;
}
inline bool cmpy(const P& a,const P& b)
{
  if (a.y!=b.y) return a.y<b.y;
  return a.x<b.x;
}
inline double dis(P a,P b)
{
  return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline double calc(P a,P b,P c)
{
  return dis(a,b)+dis(a,c)+dis(b,c);
}
double ou,res=inf;
void solve(int l,int r,const vector<P> &Py)
{
//  if (r-l+1<3) return inf;
  if (r-l<10) {
      for (int i=l;i<r;i++)
       for (int j=i+1;j<r;j++)
        for (int k=j+1;k<=r;k++)
         ou=calc(px[i],px[j],px[k]),
         res=min(res,ou); return;
  }
  int mid=(l+r)/2;
  int tmp=(px[mid].x+px[mid+1].x)/2;
//  double res=inf;
  vector<P> py1;py1.reserve(mid-l+1);
  vector<P> py2;py2.reserve(r-mid);
  fo(i,0,(int)Py.size()-1)
  {
    if (Py[i].x<tmp) py1.push_back(Py[i]);
    else py2.push_back(Py[i]);
  }
  solve(l,mid,py1),solve(mid+1,r,py2);
  int up,head=0;
  if (res>inf/2) up=bil*2;
  else up=(int)(res/2);
  static vector<P> temp;
  temp.clear();
  temp.reserve(r-l+1);
  fo(i,0,r-l)
  {
    P p=Py[i];
    if (abs(p.x-tmp)>up) continue;
    while (head<(int)temp.size()&&p.y-temp[head].y>up) head++;
    fo (i,head,(int)temp.size()-1)
    {
      fo(j,i+1,(int)temp.size()-1)
      res=min(res,calc(p,temp[i],temp[j]));
    }
    temp.push_back(p);
  }
  return;
}
int main(int argc, char *argv[])
{
  read(n);
  fo(i,1,n)
  read(px[i].x),read(px[i].y),px[i].x=px[i].x*2-bil/2,px[i].y=px[i].y*2-bil/2,py.push_back(px[i]);
  sort(px+1,px+n+1,cmpx);
  sort(py.begin(),py.end(),cmpy);
  solve(1,n,py);
  printf("%0.13lf",res/2);
  return 0;
}

 

以上是关于GCJ2009B&JZOJ 4033 Min Perimeter的主要内容,如果未能解决你的问题,请参考以下文章

「GCJ 2009 WF B」Min Perimeter

JZOJ 1039. SCOI2009windy数

JZOJ3966 Sabotage 题解

BZOJ 4033: [HAOI2015]树上染色

JZOJ 1667 ( bzoj 1801 ) [ AHOI 2009 ] 中国象棋 —— DP

JZOJ 1036. SCOI2009迷路