Jack Straws
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 2911   Accepted: 1322

Description

In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are connected by a path of touching straws. You will be given a list of the endpoints for some straws (as if they were dumped on a large piece of graph paper) and then will be asked if various pairs of straws are connected. Note that touching is connecting, but also two straws can be connected indirectly via other connected straws.

Input

Input consist multiple case,each case consists of multiple lines. The first line will be an integer n (1 < n < 13) giving the number of straws on the table. Each of the next n lines contain 4 positive integers,x1,y1,x2 and y2, giving the coordinates, (x1,y1),(x2,y2) of the endpoints of a single straw. All coordinates will be less than 100. (Note that the straws will be of varying lengths.) The first straw entered will be known as straw #1, the second as straw #2, and so on. The remaining lines of the current case(except for the final line) will each contain two positive integers, a and b, both between 1 and n, inclusive. You are to determine if straw a can be connected to straw b. When a = 0 = b, the current case is terminated.

When n=0,the input is terminated.

There will be no illegal input and there are no zero-length straws.

Output

You should generate a line of output for each line containing a pair a and b, except the final line where a = 0 = b. The line should say simply "CONNECTED", if straw a is connected to straw b, or "NOT CONNECTED", if straw a is not connected to straw b. For our purposes, a straw is considered connected to itself.

Sample Input

  1. 7
  2. 1 6 3 3
  3. 4 6 4 9
  4. 4 5 6 7
  5. 1 4 3 5
  6. 3 5 5 5
  7. 5 2 6 3
  8. 5 4 7 2
  9. 1 4
  10. 1 6
  11. 3 3
  12. 6 7
  13. 2 3
  14. 1 3
  15. 0 0
  16.  
  17. 2
  18. 0 2 0 0
  19. 0 0 0 1
  20. 1 1
  21. 2 2
  22. 1 2
  23. 0 0
  24.  
  25. 0

Sample Output

  1. CONNECTED
  2. NOT CONNECTED
  3. CONNECTED
  4. CONNECTED
  5. NOT CONNECTED
  6. CONNECTED
  7. CONNECTED
  8. CONNECTED
  9. CONNECTED

Source


 
  判断两线段相交 + 并查集
  一开始以为是简单的判断两线段相交问题,提交WA,后来发现还要用到并查集,因为这道题允许2条线段通过其他线段间接的相交,这就要求通过亲戚关系查找2条线段是否在同一集合。我一看正好是下学期数据结构的知识,就趁机熟悉了一遍。自己敲上了并查集的模板,判断两线段相交直接套用了模板,提交AC。
 
  并查集模板
  1. int UFS_NUM; //并查集中元素总数
  2. typedef struct node{
  3. int data; //节点对应的编号
  4. int rank; //节点对应秩
  5. int parent; //节点对应的双亲下标
  6. }UFSTree; //并查集树的节点类型
  7. void MAKE_SET(UFSTree t[]) //初始化并查集树
  8. {
  9. int i;
  10. for(i=;i<=UFS_NUM;i++){
  11. t[i].data = i; //数据为该点编号
  12. t[i].rank = ; //秩初始化为0
  13. t[i].parent = i; //双亲初始化为指向自己
  14. }
  15. }
  16. int FIND_SET(UFSTree t[],int x) //在x所在的子树中查找集合编号
  17. {
  18. if(t[x].parent == x) //双亲是自己
  19. return x; //双亲是自己,返回 x
  20. else //双亲不是自己
  21. return FIND_SET(t,t[x].parent); //递归在双亲中查找x
  22. }
  23. void UNION(UFSTree t[],int x,int y) //将x和y所在的子树合并
  24. {
  25. x = FIND_SET(t,x); //查找 x 所在分离集合树的编号
  26. y = FIND_SET(t,y); //查找 y 所在分离集合树的编号
  27. if(t[x].rank > t[y].rank) //y 节点的秩小于 x节点的秩
  28. t[y].parent = x; //将 y 连接到 x 节点上,x 作为 y 的双亲节点
  29. else{ //y 节点的秩大于等于 x 节点的秩
  30. t[x].parent = y; //将 x 连接到 y 节点上,y 作为 x 的双亲节点
  31. if(t[x].rank==t[y].rank) //x 和 y的双亲节点秩相同
  32. t[y].rank++; //y 节点的秩增 1
  33. }
  34. }
 
  题目代码:
  1. #include <iostream>
  2. using namespace std;
  3. /*--------- 并查集 模板 ------------*/
  4. int UFS_NUM; //并查集中元素总数
  5. typedef struct node{
  6. int data; //节点对应的编号
  7. int rank; //节点对应秩
  8. int parent; //节点对应的双亲下标
  9. }UFSTree; //并查集树的节点类型
  10. void MAKE_SET(UFSTree t[]) //初始化并查集树
  11. {
  12. int i;
  13. for(i=;i<=UFS_NUM;i++){
  14. t[i].data = i;
  15. t[i].rank = ;
  16. t[i].parent = i;
  17. }
  18. }
  19. int FIND_SET(UFSTree t[],int x) //在x所在的子树中查找集合编号
  20. {
  21. if(t[x].parent == x)
  22. return x;
  23. else
  24. return FIND_SET(t,t[x].parent);
  25. }
  26. void UNION(UFSTree t[],int x,int y) //将x和y所在的子树合并
  27. {
  28. x = FIND_SET(t,x);
  29. y = FIND_SET(t,y);
  30. if(t[x].rank > t[y].rank)
  31. t[y].parent = x;
  32. else{
  33. t[x].parent = y;
  34. if(t[x].rank==t[y].rank)
  35. t[y].rank++;
  36. }
  37. }
  38.  
  39. /*--------- 判断两线段相交 模板 ------------*/
  40. const double eps=1e-;
  41. struct point { double x, y; };
  42. double min(double a, double b) { return a < b ? a : b; }
  43. double max(double a, double b) { return a > b ? a : b; }
  44. bool inter(point a, point b, point c, point d){
  45. if ( min(a.x, b.x) > max(c.x, d.x) ||
  46. min(a.y, b.y) > max(c.y, d.y) ||
  47. min(c.x, d.x) > max(a.x, b.x) ||
  48. min(c.y, d.y) > max(a.y, b.y) ) return ;
  49. double h, i, j, k;
  50. h = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
  51. i = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);
  52. j = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);
  53. k = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);
  54. return h * i <= eps && j * k <= eps;
  55. }
  56.  
  57. /*---------- 代码实现 -----------*/
  58. struct line
  59. {
  60. point p1;
  61. point p2;
  62. };
  63. int main()
  64. {
  65. int n;
  66. UFSTree t[];
  67. while(cin>>n){
  68. if(n==) break;
  69. UFS_NUM = n;//确定并查集树中元素总数
  70. MAKE_SET(t); //初始化并查集
  71. line l[];
  72. for(int i=;i<=n;i++)
  73. cin>>l[i].p1.x>>l[i].p1.y>>l[i].p2.x>>l[i].p2.y;
  74. for(int i=;i<=n;i++) //根据关系生成关系树
  75. for(int j=;j<=n;j++){
  76. if(i==j) continue;
  77. if(inter(l[i].p1,l[i].p2,l[j].p1,l[j].p2)){ //如果相交,有亲戚关系
  78. UNION(t,i,j); //合并相关集合
  79. }
  80. }
  81. int l1,l2;
  82. while(cin>>l1>>l2){
  83. if(l1== && l2==)
  84. break;
  85. l1 = FIND_SET(t,l1);
  86. l2 = FIND_SET(t,l2);
  87. if(l1 == l2)
  88. cout<<"CONNECTED"<<endl;
  89. else
  90. cout<<"NOT CONNECTED"<<endl;
  91. }
  92. }
  93. return ;
  94. }

poj 1127:Jack Straws(判断两线段相交 + 并查集)的更多相关文章

  1. TOJ1840: Jack Straws 判断两线段相交+并查集

    1840: Jack Straws  Time Limit(Common/Java):1000MS/10000MS     Memory Limit:65536KByteTotal Submit: 1 ...

  2. poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

    Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...

  3. hdu 1147:Pick-up sticks(基本题,判断两线段相交)

    Pick-up sticks Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  4. POJ 1127 Jack Straws(计算几何)

    题目链接 抄的模版,居然1Y了.就是简单的线段相交+并查集. #include <iostream> #include <cstring> #include <cstdi ...

  5. You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3276 ...

  6. hdu 1086:You can Solve a Geometry Problem too(计算几何,判断两线段相交,水题)

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  7. hdu 1558 线段相交+并查集

    题意:要求相交的线段都要塞进同一个集合里 sol:并查集+判断线段相交即可.n很小所以n^2就可以水过 #include <iostream> #include <cmath> ...

  8. [poj 1127]Jack Straws[线段相交][并查集]

    题意: 给出一系列线段,判断某两个线段是否连通. 思路: 根据线段相交情况建立并查集, 在同一并查集中则连通. (第一反应是强连通分量...实际上只要判断共存即可, 具体的方向啊是没有关系的..) 并 ...

  9. TTTTTTTTTTTTTT poj 1127 Jack Straws 线段相交+并查集

    题意: 有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通) #include <iostream> #include <cstdio> ...

随机推荐

  1. 【转】MVC4验证用户登录特性实现方法

    在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性. // 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问. [AttributeUsage(Attribu ...

  2. 关于视频YUV

    这里有一篇摘自MSDN的文章.介绍了YUV视频数据格式. About YUV Video Digital video is often encoded in a YUV format. This ar ...

  3. UNIX网络编程卷2进程间通信读书笔记(二)—管道 (1)

    一.管道 管道的名称很形象,它就像是一个水管,我们从一端到水然后水从令一端流出.不同的是这里说的管道的两边都是进程.从一端往管道里写数据,其它进程可以从管道的另一端的把数据读出,从而实现了进程间通信的 ...

  4. potplayer 网页调用potplayer播放本地视频

      网页调用potplayer播放本地视频 CreateTime--2018年1月3日10:36:24 Author:Marydon 源码展示: <!DOCTYPE html> <h ...

  5. Google C++ Coding Style 学习笔记

    写在前面:最新公司马上就要开始开发一款视觉产品,工程量较大,且需要对客户提供可以二次开 发的SDK,整个项目用C++编写. 这就对代码质量提出了非常高的要求,同时,如何设计出优雅稳定的API也是相当大 ...

  6. linux shell 总结

    .#!指定执行脚本的shell 如果不写的话,用系统默认的shell s shell是所有linux ,unix都支持的 .#开始的行表示注释(不限于行首) 命令建议写绝对路径 执行: ./examp ...

  7. Ubuntu中类似任务管理器的东西?

    Ubuntu里面有没有类似windows中任务管理器的东西呢?怎么打开?谢谢!!!   ================================ 检举| 2009-02-01 16:50提问者 ...

  8. 关闭windows打印服务

    1.关闭打印服务:开始-运行-services.msc或打开控制面板-管理工具-服务,打开服务列表,找到Print Spooler(打印服务),关闭(右击,点“关闭”).2.删除打印缓存:进入c:\\ ...

  9. Mysql 创建表和删除表

    在数据库中创建一张表的基本语法如下: CREATE TABLE tablename (column_name_1 column_type_1 constraints, column_name_2 co ...

  10. mongodb查询实练

    1.mongodb中如何查询 (a=1 or b=2) and (c=3 or d=4)//格式:db.collection.find({"$and":[{第一个条件},{第二个条 ...