C++板子

本文介绍了如何使用圆方树数据结构实现并行划分和合并操作,以及旋转卡壳问题的解决方案。通过结构化的 Tarjan 算法处理连通分量,并用C++代码展示了如何根据坐标对二维图形进行排序和处理碰撞检测。涉及的技术包括图的遍历、深度优先搜索和双端队列在算法中的应用。
摘要由CSDN通过智能技术生成

圆方树

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值