HD 1542 Segment set 並查集+幾何

Segment set

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5309    Accepted Submission(s): 2049


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

題目解析:並查集,該題的難點主要是對線段相交的判斷

代碼如下:

# include<stdio.h>
# include<string.h>
# include<math.h>
int f[1005];
int n;
int find(int x) 
{
 return x == f[x] ? x : f[x]=find(f[x]);
}
struct point{
    double x,y;
};
struct node{
    point s,e;
}a[1005];
double product(point &a, point &b, point &c){
   double x1,y1,x2,y2;
   x1 = a.x - c.x; y1 = a.y - c.y;
   x2 = b.x - c.x; y2 = b.y - c.y;
   return (x1*y2 - x2*y1);
}

bool intersect(node &a, node &b){                 //判斷線段是不是相交
    if (
        product(a.s,a.e,b.s)*product(a.s,a.e,b.e)<=0 &&
        product(b.s,b.e,a.s)*product(b.s,b.e,a.e)<=0 ) return 1;
    return 0;
}

int main(){
int t;    
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n+10;i++)
        f[i]=i;
        int k1=0,k2=0;        
        while(n--)
        {
        getchar();            
        char cc;
        scanf("%c",&cc);
        if(cc=='P')
        {  
            k1++;
            scanf("%lf %lf %lf %lf",&a[k1].s.x,&a[k1].s.y,&a[k1].e.x,&a[k1].e.y);  
            for(int i=1;i<k1;i++)
            {     
                if(intersect(a[k1],a[i]))    //如果相交
                {   
                 int c3=find(i);        //連接
                 int c4=find(k1);
                 if(c3!=c4)
                 f[c3]=c4;
                }         
            }
        }
        else if(cc=='Q'){ 
            int m;
            scanf("%d",&m);
            int count=0;
            int c1=find(m);
            for(int i=1;i<=k1;i++)
            {   
                int c2=find(i);
                if(c2==c1)
                count++;
            }
            printf("%d\n",count);
        }
        }
        if(t)
        printf("\n");
    }
    return 0;
}

發佈了189 篇原創文章 · 獲贊 77 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章