hdu1558(并查集和简单几何的结合)
来源:互联网 发布:js 设置session属性值 编辑:程序博客网 时间:2024/05/19 19:43
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
首先这题就得解决线段相交的判断问题,欢迎观看本博客的简单几何内容;
然后重点来了,并查集,还是和基础并查集一样儿一样儿的,不过,这里有个记录问题,记录每个父亲的儿子数量,我用num数组来记录,在合并的时候将后来的父亲加上先前两个父亲的num值就ok了,不过写博客的时候突然想到了一种脑洞办法——遍历(hhhhhhhhh)试了一下也还是过了,艾玛自己想数组的办法想了好久好久结果一来写博客想到了脑洞办法竟然也可以过,亏我想数组办法调试了好久好久啊啊啊啊!!!
#include <iostream>#include<algorithm>#include<stdio.h>#include<memory.h>using namespace std;typedef struct node{ double x,y;}Point;typedef struct line{ Point start,end;}vector;double mul(Point p1,Point p2,Point p0){ return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);}bool cross(vector v1,vector v2){ if(max(v1.start.x,v1.end.x)>=min(v2.start.x,v2.end.x)&& max(v2.start.x,v2.end.x)>=min(v1.start.x,v1.end.x)&& max(v1.start.y,v2.end.y)>=min(v2.start.y,v2.end.y)&& max(v2.start.y,v2.end.y)>=min(v1.start.y,v1.end.y)&& mul(v2.start,v1.end,v1.start)*mul(v1.end,v2.end,v1.start)>=0&& mul(v1.start,v2.end,v2.start)*mul(v2.end,v1.end,v2.start)>=0 ) return true; return false;}vector f[100010];int fa[100010];int num[100010];int ff(int x){ int tem=fa[x]; if(tem!=x) fa[x]=ff(tem); return fa[x];}void join(int a,int b){ int tem=num[fa[ff(a)]]+num[fa[ff(b)]]; fa[ff(a)]=fa[ff(b)]; // cout<<a<<' '<<b<<endl; // cout<<fa[ff(a)]<<endl; // cout<<" num[fa[ff(a)]] = "<<num[fa[ff(a)]]<<" num[fa[ff(b)]] = "<<num[fa[ff(a)]]<<endl; num[fa[ff(a)]]=tem; //cout<<a<<" and "<<b<<"de father shi "<<ff(a)<<endl; // cout<<"zhe ge ji he bao han "<<num[fa[ff(a)]]<<" ge xian duan"<<endl;}int main(){ int t; scanf("%d",&t); for(int u=0;u<t;u++) { for(int i=0;i<100010;i++) fa[i]=i; memset(num,0,sizeof(num)); int n; scanf("%d",&n); int g=0; for(int i=1;i<=n;i++) { char cc;scanf(" %c",&cc); if(cc=='P') { g++; scanf("%lf%lf%lf%lf",&f[g].start.x,&f[g].start.y,&f[g].end.x,&f[g].end.y); num[g]++; for(int j=1;j<g;j++) if(cross(f[g],f[j])>0&&ff(fa[g])!=ff(fa[j])) join(fa[g],fa[j]); } else { int p; scanf("%d",&p); printf("%d\n",num[ff(fa[p])]); } } if(u!=t-1) printf("\n"); } return 0;}
下面是脑洞代码:
#include <iostream>#include<algorithm>#include<stdio.h>#include<memory.h>using namespace std;typedef struct node{ double x,y;}Point;typedef struct line{ Point start,end;}vector;double mul(Point p1,Point p2,Point p0){ return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);}bool cross(vector v1,vector v2){ if(max(v1.start.x,v1.end.x)>=min(v2.start.x,v2.end.x)&& max(v2.start.x,v2.end.x)>=min(v1.start.x,v1.end.x)&& max(v1.start.y,v2.end.y)>=min(v2.start.y,v2.end.y)&& max(v2.start.y,v2.end.y)>=min(v1.start.y,v1.end.y)&& mul(v2.start,v1.end,v1.start)*mul(v1.end,v2.end,v1.start)>=0&& mul(v1.start,v2.end,v2.start)*mul(v2.end,v1.end,v2.start)>=0 ) return true; return false;}vector f[100010];int fa[100010];int ff(int x){ int tem=fa[x]; if(tem!=x) fa[x]=ff(tem); return fa[x];}void join(int a,int b){ fa[ff(a)]=fa[ff(b)];}int main(){ int t; scanf("%d",&t); for(int u=0;u<t;u++) { for(int i=0;i<100010;i++) fa[i]=i; int n; scanf("%d",&n); int g=0; for(int i=1;i<=n;i++) { char cc;scanf(" %c",&cc); if(cc=='P') { g++; scanf("%lf%lf%lf%lf",&f[g].start.x,&f[g].start.y,&f[g].end.x,&f[g].end.y); for(int j=1;j<g;j++) if(cross(f[g],f[j])>0&&ff(fa[g])!=ff(fa[j])) join(fa[g],fa[j]); } else { int p; scanf("%d",&p); int t=ff(p),s=0; for(int i=0;i<=g;i++) if(ff(i)==t) s++; printf("%d\n",s); } } if(u!=t-1) printf("\n"); } return 0;}
0 0
- hdu1558(并查集和简单几何的结合)
- hdu1558 几何处理 + 并查集
- hdu1558(并查集)
- HDU1558 Segment set(计算几何+并查集)
- Segment set(hdu1558并查集+计算机和)
- hdu1558 Segment set (判断线段相交+并查集)
- 【计算几何初步-线段相交+并查集】【HDU1558】Segment set
- hdu1558并查集+线段相交
- hdu1558--并查集+判断线段相交
- hdu1558线段相交与并查集
- hdu1558 Segment set(线段是否有交点+并查集)
- HDU1558 - Segment set 并查集 + 判断线段相交
- poj 1127 简单几何+并查集
- HDU 1272 并查集 图和并查集的结合
- poj2236(并查集+计算几何)
- poj1127(计算几何,并查集)
- Hdu 1558 Segment set(并查集+几何)
- poj3293(几何扫描线+并查集)
- easyUI设置textbox的值
- Commons lang3 包ArrayUtils类使用
- 九度OJ 题目1464:Hello World for U
- CompareNoCase与Compare
- 前端学习
- hdu1558(并查集和简单几何的结合)
- UVALive 4730 Kingdom(线段树区间修改+并查集)
- Ubuntu 14.04 FTP服务器--vsftpd的安装和配置
- POJ 1639 最小度限制生成树
- 关于vs2013中使用partial类后仍提示某成员变量不存在时的问题解决
- 隔行变色
- lua 环境设置
- 图片延迟加载
- Eclipse快捷键 10个最有用的快捷键