zoukankan      html  css  js  c++  java
  • 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
    ",getAbs(parent[getParent(num)]));
    			}
    		}
    		if(t!=0)
    		{
    			printf("
    ");
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    堆栈学习
    需要阅读的书籍
    Rust Book Lang Ch.19 Fully Qualified Syntax, Supertraits, Newtype Pattern, type aliases, never type, dynamic sized type
    Rust Lang Book Ch.19 Placeholder type, Default generic type parameter, operator overloading
    Rust Lang Book Ch.19 Unsafe
    Rust Lang Book Ch.18 Patterns and Matching
    Rust Lang Book Ch.17 OOP
    Rust Lang Book Ch.16 Concurrency
    Rust Lang Book Ch.15 Smart Pointers
    HDU3966-Aragorn's Story-树链剖分-点权
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3180096.html
Copyright © 2011-2022 走看看