二维凸包
Andrew
struct Point{
double x, y;
friend Point operator-(Point a, Point b){
return (Point){a.x - b.x, a.y - b.y};
}
friend bool operator<(Point a, Point b){
return (a.x == b.x)? a.y < b.y : a.x < b.x;
}
}p[N];
int n, tst, st[N];
bool vis[N];
double dot(Point a, Point b){ //内积,点积
return a.x * b.x + a.y * b.y;
}
double cross(Point a, Point b){ //外积,叉积
return a.x * b.y - b.x * a.y;
}
double dis(Point a, Point b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double Andrew(){
sort(p + 1, p + n + 1);
tst = 0;
for(int i = 1; i <= n; i++){
while(tst >= 2 && cross(p[st[tst - 1]] - p[st[tst]], p[i] - p[st[tst]]) > 0)
vis[st[tst--]] = 0;
st[++tst] = i, vis[i] = 1;
}
vis[1] = 0;
for(int i = n; i > 0; i--){
if(vis[i])
continue;
while(tst >= 2 && cross(p[st[tst - 1]] - p[st[tst]], p[i] - p[st[tst]]) > 0)
vis[st[tst--]] = 0;
st[++tst] = i, vis[i] = 1;
}
double ans = 0;
for(int i = 2; i <= tst; i++)
ans += dis(p[st[i - 1]], p[st[i]]);
return ans;
}