Segment set
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5104 Accepted Submission(s): 1967
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
Author
LL
Source
HDU 2006-12 Programming Contest
Recommend
LL | We have carefully selected several similar problems for you: 1811 1198 3172 3038 3234
才刚做计算几何的题没多久就遇到了并查集的内容,看来并查集真要好好掌握啊!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 1005;
struct point{
double x,y;
};
struct segment{
point s,e;
}a[maxn];
int i,j,k,n,tot;
int f[maxn],ans[maxn];
char cc;
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(segment &a, segment &b){
if (/*max(a.s.x,a.e.x)>=min(b.s.x,b.e.x) &&
max(a.s.y,a.e.y)>=min(b.s.y,b.e.y) &&
max(b.s.x,b.e.x)>=min(a.s.x,a.e.x) &&
max(b.s.y,b.e.y)>=min(a.s.y,a.e.y) &&8*/
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 Find(int x) {
if (f[x]==x) return x;
return f[x] = Find(f[x]);
}
void Merge(int x, int y){
int fx = Find(x), fy = Find(y);
if (fx!=fy) {
f[fx] = fy;
ans[fy] += ans[fx];
}
}
int main(){
int T;
scanf("%d",&T);
while (T--) {
tot = 0;
for (i=1; i<=1000; i++) ans[i] = 1;
for (i=1; i<=1000; i++) f[i] = i;
scanf("%d",&n);
while (n--) {
cin >> cc;
if (cc=='P') {
tot++;
scanf("%lf %lf %lf %lf",&a[tot].s.x,&a[tot].s.y,&a[tot].e.x,&a[tot].e.y);
for (i=1; i<=tot-1; i++)
if (intersect(a[i],a[tot])) {
Merge(tot,i);
}
}
else {
scanf("%d",&k);
printf("%d\n",ans[Find(k)]);
}
}
if (T) printf("\n");
}
return 0;
}