POJ 1127 Jack Straws

Description

给n个线段,再个m个查询,问两个线段是否相连

reference

《挑战程序设计竞赛(第二版)》

Code

#include <cstdio> 
#include <cmath>
#include <iostream>
using namespace std;

const int maxn = 13;
const int maxm = 200;
const double eps = 1e-10;

int n;
//考虑误差的加法
double add(const double &a, const double &b)
{
  if (abs(a + b) < eps * (abs(a) + abs(b))) return 0;
  return a + b;
}

struct P
{
  double x, y;
  //两个构造函数 必须都写
  P() {}
  P(double x, double y) : x(x), y(y) {}
  //向量加法
  P operator + (P p)
  {
    return P(add(x, p.x), add(y, p.y));
  }
  //向量减法
  P operator - (P p)
  {
    return P(add(x, -p.x), add(y, -p.y));
  }
  //向量数乘
  P operator * (double d)
  {
    return P(x * d, y * d);
  }
  //向量 dot x1*x2+y1*y2
  double dot(P p)
  {
    return add(x * p.x, y * p.y);
  }
  //向量 det x1y2-x2y1
  double det(P p)
  {
    return add(x * p.y, -y * p.x);
  }
};
//判断点p是否在 线段p1-p2上
bool on_seg(P p1, P p2, P q)
{
  return (p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0;
}
//求交点
P intersection(P p1, P p2, P q1, P q2)
{
  return p1 + (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));
}

void solve()
{
  P p[maxn], q[maxn];
  for (int i = 0; i < n; i++)
  {
    int x1, y1, x2, y2;
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    p[i].x = x1;
    p[i].y = y1;
    q[i].x = x2;
    q[i].y = y2;
  }
  bool g[maxn][maxn] = {false};
  for (int i = 0; i < n; i++)
  {
    g[i][i] = true;
    for (int j = 0; j < i; j++)
    //如果平行
      if ((p[i] - q[i]).det(p[j] - q[j]) == 0)
        g[i][j] = g[j][i] = on_seg(p[i], q[i], p[j])
                        || on_seg(p[i], q[i], q[j])
                        || on_seg(p[j], q[j], p[i])
                        || on_seg(p[j], q[j], q[i]);
      else
      {
        //求交点
        P r = intersection(p[i], q[i], p[j], q[j]);
        g[i][j] = g[j][i] = on_seg(p[i], q[i], r) && on_seg(p[j], q[j], r);
      }
  }
  //判断是否相连
  for (int k = 0; k < n; k++)
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        g[i][j] |= g[i][k] && g[k][j];
  for (int i = 0; ; i++)
  {
    int a, b;
    scanf("%d%d", &a, &b);
    if (a == 0 && b == 0) break;
    puts(g[a-1][b-1] ? "CONNECTED" : "NOT CONNECTED");` `` } } int main() { for(;;) { scanf("%d", &n); if (n == 0) break; solve(); } }

你可能感兴趣的:(POJ 1127 Jack Straws)