HDOJ 1558 Segment set(并查集 + 线段判交)
来源:互联网 发布:mac豆沙色口红推荐 编辑:程序博客网 时间:2024/05/22 05:28
Segment set
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.
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
110P 1.00 1.00 4.00 2.00P 1.00 -2.00 8.00 4.00Q 1P 2.00 3.00 3.00 1.00Q 1Q 3P 1.00 4.00 8.00 2.00Q 2P 3.00 3.00 6.00 -2.00Q 5
Sample Output
12225
解题思路:如果两条线段相交,就把它们放到同一个集合里,然而如何判断两条线段是否相交呢?我也不会。。。在网上找了一份线段判交的模板,结合着并查集写出来了。。。
代码如下:
#include <algorithm>#include <cctype>#include <climits>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <map>#include <queue>#include <set>#include <stack>#include <vector>#define EPS 1e-6#define INF INT_MAX / 10#define LL long long#define MOD 100000000#define PI acos(-1.0)struct Point{ double x; double y;};struct Line{ Point begin; Point end;};const int maxn = 1005;int par[maxn],rank[maxn],num[maxn];Line line[maxn];void init(int n){ for(int i = 1;i <= n;i++){ par[i] = i; rank[i] = 0; num[i] = 1; }}int find(int x){ return par[x] == x ? x : par[x] = find(par[x]);}void unite(int x,int y){ x = find(x); y = find(y); if(x == y) return ; if(rank[x] < rank[y]){ par[x] = y; num[y] += num[x]; num[x] = 0; } else{ par[y] = x; num[x] += num[y]; num[y] = 0; if(rank[x] == rank[y]) rank[x]++; }}bool onSegment(Point p,Point q,Point r){ if(q.x <= std::max(p.x,r.x) && q.x >= std::min(p.x,r.x) && q.y <= std::max(p.y,r.y) && q.y >= std::min(p.y,r.y)) return 1; return 0;}int orientation(Point p,Point q,Point r){ int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); if(val == 0) return 0; return val > 0 ? 1 : 2;}bool doIntersect(Point p1,Point q1,Point p2,Point q2){ int o1 = orientation(p1,q1,p2); int o2 = orientation(p1,q1,q2); int o3 = orientation(p2,q2,p1); int o4 = orientation(p2,q2,q1); if(o1 != o2 && o3 != o4) return 1; if(o1 == 0 && onSegment(p1,p2,q1)) return 1; if(o2 == 0 && onSegment(p1,q2,q1)) return 1; if(o3 == 0 && onSegment(p2,p1,q2)) return 1; if(o4 == 0 && onSegment(p2,q1,q2)) return 1; return false;}int main(){ char opt[3]; int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); init(n); int cnt = 1; for(int i = 0;i < n;i++){ scanf("%s",opt); if(opt[0] == 'P'){ scanf("%lf %lf %lf %lf",&line[cnt].begin.x,&line[cnt].begin.y,&line[cnt].end.x,&line[cnt].end.y); if(cnt > 1){ for(int i = 1;i < cnt;i++){ if(doIntersect(line[i].begin,line[i].end,line[cnt].begin,line[cnt].end)){ unite(i,cnt); } } } cnt++; } if(opt[0] == 'Q'){ int k; scanf("%d",&k); k = find(k); printf("%d\n",num[k]); } } if(t) printf("\n"); } return 0;}
0 0
- HDOJ 1558 Segment set(并查集 + 线段判交)
- [HDOJ 1558] Segment set [线段相交+并查集]
- HDU 1558 Segment set (并查集+线段相交)
- hdu 1558 Segment set(并查集+线段相交)
- hdu 1558 Segment set 线段相交+并查集
- HDU 1558 Segment set(线段相交+并查集)
- HDU 1558 Segment set(判断线段相交+并查集)
- hdu 1558 Segment set(线段相交+并查集)
- HDU 1558 Segment set 并查集 线段相交
- HDU-1558,Segment set,并查集+线段相交模拟
- HDU 1158 Segment set(线段相交 并查集)
- hdu1558 Segment set (判断线段相交+并查集)
- poj 1127 Jack Straws 线段判交+并查集
- 杭电 1558 Segment set(并查集+线段相交)
- hdu 1558 Segment set(并查集+判断线段是否相交)
- HDU 1558 Segment set(并查集+判断线段相交)
- 文章标题 HDU 1558 : Segment set (并查集+线段相交)
- hdu 1558 Segment set(判线段相交模版)
- (POJ 3494)Largest Submatrix of All 1’s (DP、单调栈)
- cocos斗地主发牌动画
- 树结构练习——排序二叉树的中序遍历
- ZZULI-oj-1913 小火山的计算能力 ( 模拟 )
- sort命令详解高级语法
- HDOJ 1558 Segment set(并查集 + 线段判交)
- hdu 4966 GGS-DDU (最小树形图)
- Scalaz(53)- scalaz-stream: 程序运算器-application scenario
- 隐私策略
- Python
- C#控制台基础 list<int>添加元素并输出实例
- 最长公共子序列
- 形参的改变如何影响实参
- JAVA中对null进行强制类型转换