杭电 HOJ 1588 Segment set 解题报告
并查集,还有判断两线段是否相交。我直接用面积的方法判断的,貌似效率略低,但是Ac还是可以的,代码如下:
#include <iostream> using namespace std; int root[1001]; int num[1001]; int find(int x) { return root[x]?(root[x]=find(root[x])):x; } void u(int x,int y) { int a=find(x); int b=find(y); if(a!=b) num[root[b]=a]+=num[b]; } struct p { double x1,y1,x2,y2; } line[1001]; double area(double a,double b,double c,double d) { return (a*d-b*c); }; bool across(p &a,p &b) { if(area(a.x2-a.x1,a.y2-a.y1,b.x1-a.x1,b.y1-a.y1)*area(a.x2-a.x1,a.y2-a.y1,b.x2-a.x1,b.y2-a.y1)<=0 && area(b.x2-b.x1,b.y2-b.y1,a.x1-b.x1,a.y1-b.y1)*area(b.x2-b.x1,b.y2-b.y1,a.x2-b.x1,a.y2-b.y1)<=0) return true; return false; } int main() { char s[2]; int cas,m,n,i,j,ans,t; scanf("%d",&cas); while(cas--) { m=1; memset(root,0,sizeof(root)); memset(num,0,sizeof(num)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s",s); if(s[0]=='P') { scanf("%lf%lf%lf%lf",&line[m].x1,&line[m].y1,&line[m].x2,&line[m].y2); root[m]=0; num[m]=1; for(j=1;j<m;j++) if(across(line[j],line[m])) u(m,j); m++; } else { scanf("%d",&t); printf("%d\n",num[find(t)]); } } if(cas) printf("\n"); } }