续
圆方树
struct f{
int to[100005*2],nxt[100005*2],head[100005],tot;
void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
return;
}
} g,t;
int cnt,low[100005],dfn[100005],stak[100005],w[100005],top,cntt,tot,n,m;
void Tarjan(int x)
{
low[x]=dfn[x]=++cnt;
stak[++top]=x;
for (int i=g.head[x];i;i=g.nxt[i])
{
if (!dfn[g.to[i]])
{
Tarjan(g.to[i]);
low[x]=min(low[x],low[g.to[i]]);
if (low[g.to[i]]==dfn[x])
{
w[++cntt]=0;
for (int u=0;u!=g.to[i];--top)
{
u=stak[top];
t.add(cntt,u);
t.add(u,cntt);
++w[cntt];
}
t.add(cntt,x);
t.add(x,cntt);
++w[cntt];
}
}
else low[x]=min(low[x],dfn[g.to[i]]);
}
}
旋转卡壳
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<deque>
using namespace std;
int n,cnt;
double ans;
struct node{
double x,y;
} d[50005],s[50005];
double cross(node p1,node p2,node p3,node p4)
{
return (p2.x-p1.x)*(p4.y-p3.y)-(p4.x-p3.x)*(p2.y-p1.y);
}
double dis(node l,node r)
{
return (r.x-l.x)*(r.x-l.x)+(r.y-l.y)*(r.y-l.y);
}
bool cmp(node x,node y)
{
double c=cross(d[1],x,d[1],y);
if (c>0||(c==0&&dis(d[0],x)<dis(d[0],y))) return 1;
return 0;
}
double getvect(node x,node y,node z)
{
return cross(z,x,z,y);
}
int main()
{
scanf("%d",&n);
node tmp;
scanf("%lf%lf",&d[1].x,&d[1].y);
for (int i=2;i<=n;i++)
{
scanf("%lf%lf",&d[i].x,&d[i].y);
if (d[i].y<d[1].y)
{
tmp=d[i];
d[i]=d[1];
d[1]=tmp;
}
}
s[1]=d[1];
sort(d+2,d+n+1,cmp);
for (int i=2;i<=n;i++)
{
while (cnt>1&&cross(s[cnt-1],s[cnt],s[cnt],d[i])<=0) cnt--;
cnt++;
s[cnt]=d[i];
}
s[++cnt]=d[1];
int p=2;
s[0]=s[cnt];
for (int i=0;i<=cnt;i++)
{
while (getvect(s[i],s[i+1],s[p])<getvect(s[i],s[i+1],s[p+1])) p=(p+1)%cnt;
ans=max(ans,max(dis(s[i],s[p]),dis(s[i+1],s[p])));
}
cout<<ans;
return 0;
}