ACAC002 C Diameter of a Convex Polygon

ここ数日幾何にハマっています。これはこの前本番で解けなかった問題。本番では全点間の距離の最大値で間に合うんじゃね?とか思って愚直な解法でやってTLEしてました(それでも22/24も通ったw)
久しぶりに問題を眺めてみると、コレこの前勉強したやつじゃんwとなったので解きました。

解法

キャリパー法で多角形をぐるんと回す。コレで勘弁してください。説明苦手です。わかりやすい解説は蟻本に載っています。

ソースコード

#include <cmath>
#include <algorithm>
#include <vector>
#include <functional>
#include <iostream>
#include <iomanip>
using namespace std;
#define eps 1e-9
#define pb push_back
double add(double a,double b)
{
	if(abs(a+b)<eps*(abs(a)+abs(b)))return 0;
	return a+b;
}
struct P
{
	double x,y;
	P (){}
	P(double x,double y):x(x),y(y){}
	P operator +(P p)
	{
		return P(add(x,p.x),add(y,p.y));
	}
	P operator -(P p)
	{
		return P(add(x,-p.x),add(y,-p.y));
	}
	P operator *(double d)
	{
		return P(x*d,y*d);
	}
	double dot(P p)
	{
		return add(x*p.x,y*p.y);
	}
	double det(P p)
	{
		return add(x*p.y,-y*p.x);
	}
};
bool comp(const P& p,const P& q)
{
	if(p.x!=q.x)return p.x<q.x;
	return p.y<q.y;
}
double dist(P p,P q)
{
	return sqrt((p-q).dot(p-q));
}
int main()
{
	vector<P> cv;
	int n;
	cin >> n;
	for(int i=0;i<n;i++)
	{
		P a;
		cin >> a.x >> a.y;
		cv.pb(a);
	}
	int i=0,j=0;
	for(int k=0;k<n;k++)
	{
		if(!comp(cv[i],cv[k]))i=k;
		if(comp(cv[j],cv[k]))j=k;
	}
	int si=i,sj=j;
	double ans=0;
	while(i!=sj||j!=si)
	{
		ans=max(ans,dist(cv[i],cv[j]));
		if((cv[(i+1)%n]-cv[i]).det(cv[(j+1)%n]-cv[j])<0)i=(i+1)%n;
		else j=(j+1)%n;
	}
	cout << setprecision(16) << ans << endl;
	return 0;
}