第五次个人赛D题 Segment set 判断线段相交+并查集
2010-08-04 14:26
441 查看
Segment set
HDU 1558 http://acm.hdu.edu.cn/showproblem.php?pid=1558Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 973 Accepted Submission(s): 396
Problem Description
A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set.
Input
In the first line there is an integer t - the number of test case. For each test case in first line there is an integer n (n<=1000) - the number of commands.
There are two different commands described in different format shown below:
P x1 y1 x2 y2 - paint a segment whose coordinates of the two endpoints are (x1,y1),(x2,y2).
Q k - query the size of the segment set which contains the k-th segment.
k is between 1 and the number of segments in the moment. There is no segment in the plane at first, so the first command is always a P-command.
Output
For each Q-command, output the answer. There is a blank line between test cases.
Sample Input
1 10 P 1.00 1.00 4.00 2.00 P 1.00 -2.00 8.00 4.00 Q 1 P 2.00 3.00 3.00 1.00 Q 1 Q 3 P 1.00 4.00 8.00 2.00 Q 2 P 3.00 3.00 6.00 -2.00 Q 5
Sample Output
1 2 2 2 5就是2部分,线段相交,如果相交就并查:#include "algorithm" #include "iostream" #include "cmath" #include "stdio.h" #include "string.h" #include "stdlib.h" using namespace std; struct TPoint { double x,y; }; struct TLineSeg { TPoint a,b; }a[1001]; double xmulti(TPoint p1,TPoint p2,TPoint p0) { //(P1-P0)*(P2-P0)的叉积 若结果为正,则<P0,P1>在<P0,P2>的顺时针方向; return((p1.x-p0.x) * (p2.y-p0.y) - (p2.x-p0.x) * (p1.y-p0.y)); } int lsinterls(TLineSeg u,TLineSeg v) { //判断2线段是否相交 return( (max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&& (max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&& (max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&& (max(v.a.y,v.b.y)>=min(u.a.y,u.b.y))&& (xmulti(v.a,u.b,u.a)*xmulti(u.b,v.b,u.a)>=0)&& (xmulti(u.a,v.b,v.a)*xmulti(v.b,u.b,v.a)>=0)); } struct boy{ //并查集 int father; }s[1001]; int getfather(int a){ //并查集 while(1){ if(s[a].father<0) return a; a=s[a].father; } } int main(){ int i,j,m,n,T,x,y,k,fin,ans,cnt,num[1001]; char ch[10]; scanf("%d",&T); while(T--){ scanf("%d",&n); for(i=0;i<=n;i++) {s[i].father=-1; num[i]=1;} //初始化 k=0; for(i=0;i<n;i++) { scanf("%s",ch); if(ch[0]=='P'){ //输入为‘P’的情况 scanf("%lf%lf%lf%lf",&a[k].a.x,&a[k].a.y,&a[k].b.x,&a[k].b.y); for(j=0;j<k;j++) if( lsinterls(a[k],a[j]) ) { //假如相交 x = getfather( k ); y = getfather( j ); if(x!=y){ s[y].father = x; num[x]+=num[y]; } } k++; } else{ //输入为‘Q’的情况 scanf("%d",&fin); printf("%d/n",num[getfather(fin-1)]); //或者不用num数组 ans=getfather(fin-1); 再用for循环寻找等于ans的个数 不过时间长一点 } } if(T) printf("/n"); } //system("pause"); return 0; }
相关文章推荐
- hdu 1558 Segment set 并查集 叉积判断线段是否相交
- hdu1558 Segment set (判断线段相交+并查集)
- HDU1558 - Segment set 并查集 + 判断线段相交
- 判断线段相交(hdu1558 Segment set 线段相交+并查集)
- HDU 1558 Segment set(判断线段相交+并查集)
- hdu 1558 线段相交判断 + 并查集
- HDU 1558 判断两个线段相交附带并查集
- hdu1558--并查集+判断线段相交
- HDU 1558 Segment set(线段相交+并查集)
- hdu 1558 判断线段相交 + 并查集
- [HDOJ 1558] Segment set [线段相交+并查集]
- hdu1558--并查集+判断线段相交
- poj 1127:Jack Straws(判断两线段相交 + 并查集)
- 【计算几何初步-线段相交+并查集】【HDU1558】Segment set
- hdu 1558 Segment set(判断线段有交点+并查集)
- hdu 1558 Segment set(线段相交+并查集)
- ccsu1359 木棒相交 (叉积线段判交,并查集判断是否属于同一个集合)
- HDU 1158 Segment set(线段相交 并查集)
- POJ 1127 Jack Straws(线段相交判断+并查集)
- HLG 1507 水神的栅栏【判断线段相交+并查集】