BZOJ1804: [Ioi2007]Flood 洪水

本文介绍了一种通过坐标排序找到并删除多边形最外层边界的算法实现。该方法首先将所有点按坐标排序,然后依次找出最外层的点,并移除这些点所构成的边界,直到所有最外层边界被删除。适用于解决计算机图形学中多边形简化等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

把点按坐标排序,每次找出最小的点,一定在最外层,再顺着把最外层的边删掉,经过了两次的边不会被冲毁。

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int n,m,y,q[N],x[N],e[N],*back=e,*f[N][4];
struct vec{
	int x,y,z;
}a[N],r[N];
bool operator<(vec u,vec v){
	return u.x<v.x||u.x==v.x&&u.y<v.y;
}
int foo(int i,int j){
	return a[i].x==a[j].x?a[i].y<a[j].y?3:1:a[i].x<a[j].x?2:0;
}
void add(int u,int v){
	f[u][foo(u,v)]=&(*back++=v);
	f[v][foo(v,u)]=&(*back++=u);
}
bool test(int i){
	for(int j=0;j!=4;++j)
		if(f[i][j])return 1;
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		a[i].z=i;
		scanf("%d%d",&a[i].x,&a[i].y);
		r[i]=a[i];
	}
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	sort(r+1,r+n+1);
	for(int i=1;i<=n;++i)
		while(test(r[i].z)){
			int l=0,j=2,k=r[i].z;
			do{
				j=j+3&3;
				while(!f[k][j])
					++j&=3;
				++x[(q[l++]=f[k][j]-e)>>1];
				k=*f[k][j];
			}while(k!=r[i].z);
			for(int j=0;j!=l;++j){
				int u=e[q[j]],v=e[q[j]^1];
				f[u][foo(u,v)]=0;
				f[v][foo(v,u)]=0;
			}
		}
	for(int i=0;i!=m;++i)
		y+=x[i]==2;
	printf("%d\n",y);
}

转载于:https://www.cnblogs.com/f321dd/p/5581160.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值