D-Dllllan and his friends
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1000010;
const double eps=1e-8;
struct point{double x,y;}P[maxn];
struct line{point a,b;};
double xmult(point p1,point p2,point p0){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double distance(point p1,point p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
point intersection(line u,line v){ //两直线交点
point ret=u.a;
double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))
/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
ret.x+=(u.b.x-u.a.x)*t;
ret.y+=(u.b.y-u.a.y)*t;
return ret;
}
point circumcenter(point a,point b,point c) //求外心
{ //求两条中垂线交点来求三角形外心
line u,v;
u.a.x=(a.x+b.x)/2;
u.a.y=(a.y+b.y)/2;
u.b.x=u.a.x-a.y+b.y;
u.b.y=u.a.y+a.x-b.x;
v.a.x=(a.x+c.x)/2;
v.a.y=(a.y+c.y)/2;
v.b.x=v.a.x-a.y+c.y;
v.b.y=v.a.y+a.x-c.x;
return intersection(u,v);
}
//最小生成树模板
int n;
double x,y;
double r;
struct edge
{
int u,v;
double w;
bool operator < (const edge &r)const
{
return w<r.w;
}
}e[maxn];
int f[maxn];
int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
}
void k(int n,int m)
{
double res=0;
int num=0;
sort(e+1,e+1+m);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
int f1=find(e[i].u);
int f2=find(e[i].v);
if(f1!=f2)
{
num++;
res+=e[i].w;
f[f1]=f2;
}
if(num==n-1)
break;
}
if(num==n-1) printf("%.10lf\n",res);
}
int main()
{
scanf("%d",&n);
point wx;
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&x,&y);
P[i].x=x,P[i].y=y;
if(i==3)
{
wx=circumcenter(P[1],P[2],P[3]);
if(wx.x!=floor(wx.x)||wx.y!=floor(wx.y))
{
printf("-1");
return 0;
}
r=distance(wx,P[1]);
}
double dis;
if(i>3)
{
dis=distance(P[i],wx);
if(fabs(r-dis)>eps)
{
printf("-1");
return 0;
}
}
}
printf("%.0lf %.0lf\n",wx.x,wx.y);
P[n+1]=wx;
int tot=0;
for(int i=1;i<=n+1;i++)
{
for(int j=1;j<=n+1;j++)
{
if(j==i) continue;
e[++tot].u=i;
e[tot].v=j;
e[tot].w=distance(P[i],P[j]);
}
}
k(n+1,tot);
return 0;
}