hdu 1558 Segment set(并查集+判断线段是否相交)

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int father[1005];
int son_cnt[1005];
char s[5];
//int cnt;

struct point
{
    double x,y;
};

point a[1005],b[1005];

int find_father(int x)
{
    int r=x;
    while(father[x]!=x)
    {
        x=father[x];
    }
    father[r]=x;
    //ans[x]++;
    return x;
}

double xmult(point a,point b,point c) //大于零代表a,b,c左转
{
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool OnSegment(point a,point b,point c) 		//a,b,c共线时有效
{
    return c.x>=min(a.x,b.x)&&c.x<=max(a.x,b.x)&&c.y>=min(a.y,b.y)&&c.y<=max(a.y,b.y);
}

bool Cross(point a,point b,point c,point d) //判断ab 与cd是否相交
{
    double d1,d2,d3,d4;
    d1=xmult(c,d,a);
    d2=xmult(c,d,b);
    d3=xmult(a,b,c);
    d4=xmult(a,b,d);
    if(d1*d2<0&&d3*d4<0)	return 1;
    else	if(d1==0&&OnSegment(c,d,a))	return 1;
    else	if(d2==0&&OnSegment(c,d,b))	return 1;
    else	if(d3==0&&OnSegment(a,b,c))	return 1;
    else	if(d4==0&&OnSegment(a,b,d))	return 1;
    return 0;
}
void mergee(int x,int y)
{
    //if(intersect3(a[x],b[x],a[y],b[y]))
    //{
        x=find_father(x);
        y=find_father(y);
        if(x!=y)
        {
            father[y]=x;
            son_cnt[x]+=son_cnt[y];
            //son_cnt[y]=son_cnt[x];
           // son_cnt[y]--;
        }
    //}
}

int main()
{
    int t;
    int cnt;
    scanf("%d",&t);
    while(t--)
    {
        //memset(ans,0,sizeof(ans));
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            father[i]=i;
            son_cnt[i]=1;
        }
        cnt=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            if(strcmp(s,"P")==0)
            {
                cnt++;
                scanf("%lf%lf%lf%lf",&a[cnt].x,&a[cnt].y,&b[cnt].x,&b[cnt].y);
                for(int j=1;j<cnt;j++)
                {
                    if(Cross(a[j],b[j],a[cnt],b[cnt]))
                        mergee(j,cnt);
                }
            }
            else
            {
                int ttt;
                scanf("%d",&ttt);
                printf("%d\n",son_cnt[find_father(ttt)]);
            }
        }
        if(t)
            printf("\n");
    }
    return 0;
}
时间: 2024-10-04 20:39:48

hdu 1558 Segment set(并查集+判断线段是否相交)的相关文章

HDU1558 - Segment set 并查集 + 判断线段相交

HDU1558 - Segment set: http://acm.hdu.edu.cn/showproblem.php?pid=1558 题目大意: 输入一些线段的端点坐标,若两线段相交,则把他们合并成一个集合,输入数据里会有k,问和k线段相交的线段的数目(包括自己) 思路: 每次输入一条线段,都从头扫描一次. 找出之前输入的线段里面,所有和其相交的线段,并且合并(合并用的是线段的ID). 就是: 并查集 + 判断线段相交 代码: #include <iostream> #include &

hdu 1558 Segment set (并查集+计算几何)

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3486    Accepted Submission(s): 1297 Problem Description A segment and all segments which are connected with it compose a segment set

hdu 1558 Segment set (并查集)

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3907    Accepted Submission(s): 1471 Problem Description A segment and all segments which are connected with it compose a segment set

HDU HDU1558 Segment set(并查集+判断线段相交)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1558 解题报告:首先如果两条线段有交点的话,这两条线段在一个集合内,如果a跟b在一个集合内,b跟c在一个集合内,那么a跟c在一个集合内.在一个平面上,有两种操作: P:在这个平面上添加一条线段 Q k:询问添加的第k条线段所在的那个集合有多少条线段 用并查集,然后就是要判断一下线段有没有交点.还有就是题目要求两个test之间要有空行,为此我还PE了一次. 1 #include<cstdio> 2

HDU 1558 Segment set (并查集+线段非规范相交)

题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. 1 //1558 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <cmath> 6 #define eps 1e-8 7 #define zero(x) (((x) > 0 ? (x) : (-x)) < e

hdu 5424 回溯+并查集判断连通性

题意:给定一个n个点n条边的无向图,判断是否存在哈密顿路径. 思路:先用并查集判断图是否连通,然后从度数最小的点开始回溯,看是否能找到一条哈密顿路径. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <set> 5 using namespace std; 6 7 const int INF = 999999; 8 const int N = 1001; 9

HDU Catch (二分图判断奇环+并查集判断联通)

Problem Description A thief is running away!We can consider the city where he locates as an undirected graph in which nodes stand for crosses and edges stand for streets. The crosses are labeled from 0 to N–1. The tricky thief starts his escaping fro

hdu 1811Rank of Tetris (并查集 + 拓扑排序)

1 /* 2 题意:这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B. 3 4 现在Lele并不是让你来帮他制作这个高手榜,他只是想知道,根据这些信息是否能够确定出这个高手榜,是的话就输出"OK". 5 否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出&quo

HDOJ Ice_cream&#39;s world I 2120【并查集判断成环】

Ice_cream's world I Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 848    Accepted Submission(s): 494 Problem Description ice_cream's world is a rich country, it has many fertile lands. Today,