【并查集】Baltic2016 Park

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34454069/article/details/88242298

分析:

很简单的并查集水题。
每个圆视为一个点,上下左右四个边界各视为一个点,

两点间距离表示:最大能穿过的圆的直径。

所以可以先把n2n^2条边的预处理出来,然后再把边权从小到大排序,询问的圆也从小到大排序即可。

判断一下几个边界是否连通,就能知道它能到达哪些点。

只不过卡精度了很难受。。。

所以得用longlong二分适合的边权。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#define SF scanf
#define PF printf
#define MAXN 3000010
#define EPS 1e-6
using namespace std;
typedef long long ll;
int fa[MAXN];
struct node{
	int u,v;
	ll val;
	node () {}
	node (int u1,int v1,double val1):u(u1),v(v1),val(val1) {}
	bool operator <(const node &a) const {
		if(val!=a.val)
			return val<a.val;	
		if(u!=a.u)
			return u<a.u;
		return v<a.v;
	}
}edge[MAXN];
struct cir{
	int x,y,r;
	bool operator <(const cir &a) const {
		if(r!=a.r)
			return r<a.r;
		if(x!=a.x)
			return x<a.x;
		return y<a.y;
	}
}p[MAXN],q[MAXN];
int get_fa(int x){
	if(fa[x]==0)
		return x;
	fa[x]=get_fa(fa[x]);
	return fa[x];	
}
void merge(int u,int v){
	u=get_fa(u);
	v=get_fa(v);
	if(u==v)
		return ;
	fa[u]=v;
}
bool check(int u,int v){
	u=get_fa(u);
	v=get_fa(v);
	return u!=v;
}
bool check(int u,int v,ll len){
	ll dx=p[u].x-p[v].x;
	ll dy=p[u].y-p[v].y;
	ll len1=dx*dx+dy*dy;
	len=len+p[u].r+p[v].r;
	return len1<len*len;
}
int n,m,w,h,tot;
ll find_dist(int u,int v){
	ll l=0,r=max(w,h);
	ll ans=r;
	while(l!=r){
		ll mid=(l+r)>>1;
		if(check(u,v,mid)){
			r=mid;
		}
		else
			l=mid+1;
	}
	return l;
}
string ans[MAXN];
int main(){
	SF("%d%d",&n,&m);
	SF("%d%d",&w,&h);
	for(int i=1;i<=n;i++)
		SF("%d%d%d",&p[i].x,&p[i].y,&p[i].r);	
	for(int i=1;i<=m;i++){
		SF("%d%d",&q[i].r,&q[i].x);
		q[i].y=i;
	}
	int L=n+1,D=n+2,R=n+3,U=n+4;
	for(int i=1;i<=n;i++){
		edge[++tot]=node(i,L,p[i].x-p[i].r);
		edge[++tot]=node(i,D,p[i].y-p[i].r);
		edge[++tot]=node(i,R,w-p[i].x-p[i].r);
		edge[++tot]=node(i,U,h-p[i].y-p[i].r);
		for(int j=i+1;j<=n;j++)
			edge[++tot]=node(i,j,find_dist(i,j));
	}
	sort(edge+1,edge+1+tot);
	sort(q+1,q+1+m);
	int top=1;
	for(int i=1;i<=m;i++){
		while(top<=tot&&edge[top].val <=2ll*q[i].r){
//			PF("{%d %d %lf}\n",edge[top].u,edge[top].v,edge[top].val);
			merge(edge[top].u,edge[top].v);
			top++;
		}
//		PF("[%d %d %d %d]\n",i,q[i].x,q[i].r,q[i].y);
		int id=q[i].x;
		if(id==1){
			ans[q[i].y]+='1';
			if(check(D,R)&&check(D,U)&&check(L,D))
				ans[q[i].y]+='2';
			if(check(U,R)&&check(L,R)&&check(U,D)&&check(L,D))
				ans[q[i].y]+='3';
			if(check(L,U)&&check(L,R)&&check(L,D))
				ans[q[i].y]+='4';
		}
		else if(id==2){
			if(check(D,R)&&check(D,U)&&check(L,D))
				ans[q[i].y]+='1';
			ans[q[i].y]+='2';
			if(check(D,R)&&check(L,R)&&check(U,R))
				ans[q[i].y]+='3';
			if(check(L,U)&&check(L,R)&&check(U,D)&&check(D,R))
				ans[q[i].y]+='4';
		}
		else if(id==3){
			if(check(U,R)&&check(L,R)&&check(U,D)&&check(L,D))
				ans[q[i].y]+='1';
			if(check(D,R)&&check(L,R)&&check(U,R))
				ans[q[i].y]+='2';
			ans[q[i].y]+='3';
			if(check(U,R)&&check(U,D)&&check(U,L))
				ans[q[i].y]+='4';
		}
		else if(id==4){
			if(check(L,U)&&check(L,R)&&check(L,D))
				ans[q[i].y]+='1';
			if(check(L,U)&&check(L,R)&&check(U,D)&&check(R,D))
				ans[q[i].y]+='2';
			if(check(U,R)&&check(U,D)&&check(U,L))
				ans[q[i].y]+='3';
			ans[q[i].y]+='4';
		}
	}
	for(int i=1;i<=m;i++)
		cout<<ans[i]<<endl;
}


展开阅读全文

A Walk in the Park

02-14

问题描述 :nnnYou are responsible for inspecting the trees located in a park, to make sure they remain healthy. The location of each tree is given to you as a point in the twodimensional plane, distinct from that of every other tree. Due to recentlyreplanted grass, you are only allowed to walk through the park along a collection of paths. Each path is described by an infinite-length horizontal or vertical line in the two-dimensional plane. No tree lies on any path.nnYou are concerned that it may not be possible to view all the trees in the park from the paths. In particular, a tree is visible only if you can view it by standing on some path while facing in a direction perpendicular to that path; there must be no intervening tree that obstructs your view. Given the geometrical configuration of the park, please report the number of visible trees. nn输入:nnnThere will be multiple input sets. For each input set, the first line will contain two integers, N and M , ( 0 < N, M<=100000 ), separated by a space. N is the number of trees, and M is the number of paths.nnThe next N lines each contain two space-separated integers, X and Y , specifying the coordinates of a tree. X and Y may be any 32-bit integers.nnnThe next M lines each describe a path (a vertical or horizontal line). They have the form x = K or y = K , with no spaces. K may be any 32-bit integer. x and y will be lower case.nnnEnd of the input is signified by a line with two space-separated 0′s. nn输出:nnnThere will be multiple input sets. For each input set, the first line will contain two integers, N and M , ( 0 < N, M<=100000 ), separated by a space. N is the number of trees, and M is the number of paths.nnThe next N lines each contain two space-separated integers, X and Y , specifying the coordinates of a tree. X and Y may be any 32-bit integers.nnnThe next M lines each describe a path (a vertical or horizontal line). They have the form x = K or y = K , with no spaces. K may be any 32-bit integer. x and y will be lower case.nnnEnd of the input is signified by a line with two space-separated 0′s.nn样例输入:nn6 3n-1 3n4 2n6 2n6 3n6 4n4 3nx=0ny=-1ny=5n1 2n2 3nx=5ny=5n0 0n样例输出:nn5n1 问答

没有更多推荐了,返回首页