hdu1558--并查集+判断线段相交

简单的计算几何题,判断两线段是否相交。将相交的两线段使用并查集归到一类中。查询时输出线段对应集合中元素的个数。

 

#include<stdio.h>



struct Point{

	double x,y;

};

struct Segment{

	Point s,e;

}node[1010];

int n,parent[1010];

int getAbs(int value)

{

	if(value>=0)return value;

	return -value;

}

int getParent(int a){

	while(parent[a]>0)a=parent[a];

	return a;

}

void Union(int a,int b)

{

	int r1 = getParent(a);

	int r2 = getParent(b);

	if(r1!=r2)

	{

		if(r1<r2)

		{

			parent[r1]+=parent[r2];//合并两个集合时,计算两个集合的元素个数

			parent[r2]=r1;

		}else{

			parent[r2]+=parent[r1];

			parent[r1]=r2;

		}

	}

}

double max(double a,double b)

{

	if(a>=b)return a;

	return b;

}

double min(double a,double b)

{

	if(a>=b)return b;

	return a;

}

/** 

* 计算向量 ps,pe的叉积

*/

double multiply(Point p,Point s,Point e)

{

	return (s.x-p.x)*(e.y-p.y)-(e.x-p.x)*(s.y-p.y);

}

int main()

{

	int t,n,i,j,num,cnt;

	char command;

	scanf("%d",&t);

	while(t--)

	{

		scanf("%d",&n);

		cnt=0;

		//初始时每个元素都是一个集合

		for(i=1;i<=n;i++)parent[i]=-1;

		for(i=1;i<=n;i++)

		{

			getchar();

			scanf("%c",&command);

			if(command=='P'){

				cnt++;

				scanf("%lf%lf%lf%lf",&node[cnt].s.x,&node[cnt].s.y,&node[cnt].e.x,&node[cnt].e.y);

				for(j=1;j<cnt;j++)

				{

					//判断第cnt个线段是否与前面的cnt-1个线段有相交。

					if(max(node[cnt].s.x,node[cnt].e.x)>=min(node[j].s.x,node[j].e.x)

						&& max(node[j].s.x,node[j].e.x)>=min(node[cnt].s.x,node[cnt].e.x)

						&& max(node[cnt].s.y,node[cnt].e.y)>=min(node[j].s.y,node[j].e.y)

						&& max(node[j].s.y,node[j].e.y)>=min(node[cnt].s.y,node[cnt].e.y)

						&& multiply(node[cnt].s,node[j].s,node[j].e)*multiply(node[cnt].e,node[j].s,node[j].e)<=0

						&& multiply(node[j].s,node[cnt].s,node[cnt].e)*multiply(node[j].e,node[cnt].s,node[cnt].e)<=0)

					{

						//有相交就合并集合

						Union(cnt,j);

					}

				}

			}else

			{

				scanf("%d",&num);

				//当parent为负数时,其绝对值就是该集合的元素个数。

				printf("%d\n",getAbs(parent[getParent(num)]));

			}

		}

		if(t!=0)

		{

			printf("\n");

		}

	}

	return 0;

}


 

 

你可能感兴趣的:(HDU)