hdu1558 Segment set(线段是否有交点+并查集)

      p时把新的线段添加进来,Q时输出与对应编号的线段同一个集合的线段数目输出。用到并查集和判断线段是否相交。

#include <iostream>
#include <cmath>
using namespace std;
#define MAX 1005
#define pre 0.000000001
struct Node
{
	double x, y;
};
struct Line
{
	Node s, e;
};
Line line[MAX];
int p[MAX];
int n, m;
char ch;
int find(int x)
{
	return x==p[x] ? x : p[x]=find(p[x]);
}
int dblcmp(double b)
{
	if (fabs(b) < pre)
	  return 0;
	return b > 0 ? 1 : -1;
} 
int cross(Node a, Node b, Node c)
{
	double x1 = a.x -c.x;
	double y1 = a.y - c.y;
	double x2 = b.x - c.x;
	double y2 = b.y - c.y;
	return x1 * y2 - x2 * y1;
}
int segcrossSimple(Line a, Line b)//判断两直线是否相交 
{
	int x1 = dblcmp(cross(a.s, a.e, b.s));
	int x2 = dblcmp(cross(a.s, a.e, b.e));
	int y1 = dblcmp(cross(b.s, b.e, a.s));;
	int y2 = dblcmp(cross(b.s, b.e, a.e));
	return (x1 * x2 <= 0) && (y1 * y2 <= 0);
}
int main()
{
	int flag = 1;
	cin>>n;
	while (n--)
	{
		cin>>m;
		int j = 1;
		for (int i=1; i<=m; i++)
		   p[i] = i; 
		for (int i=1; i<=m; i++)
		{
		    cin>>ch;
			if (ch=='P')
			{
				cin>>line[j].s.x>>line[j].s.y>>line[j].e.x>>line[j].e.y;
				for (int k=1; k<=j; k++)
				 if (segcrossSimple(line[j], line[k]))
				 {
				 	int x = find(j);
				 	int y = find(k);
				 	if (x!=y)
				 		p[x] = y;
				 }
				j++;
			}	
			else
			{
				int r, ans = 0;
				cin>>r;
				int fa = find(r);
				for (int k=1; k<=j; k++)
				  if (find(k)==fa)
			         ans++;
			    
			    cout<<ans<<endl;
			}
		}
		if (n)
		  cout<<endl;
	}
	return 0;
}


    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值