gym101485C Cleaning Pipes 几何判两线段相交 + 二分图判定

gym101485C

题意:
有 n 个水井,从每个水井可以发出一些管道,从不同的水井发出的管道的相交点就是清洁点。要在某些管道上放出一些机器人,它们会清洁所有该条管道上的清洁点。
现在要把所有的清洁点都清理一遍,但是两条相交的管道不能同时都放机器人。问你是否存在一种可行的放机器人的方案。
tags:
我们把管道当作点,如果两条管道相交,就把这两个点相连,最后判一下这个图能否构成二分图,如能,即可行。
题目给出一条管道,只给出它的起点和终点,所以我们先要对两线段判断它们是否相交。

// gym101485C
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 1005;

struct Point { double x, y; };
double Cross(Point A, Point B) { return A.x*B.y - A.y*B.x; }
double Length(Point A) { return sqrt(A.x*A.x + A.y*A.y); }
double Point_To_Line(Point P, Point A, Point B) {
    Point AB = (Point){ B.x-A.x, B.y-A.y };
    Point AP = (Point){ P.x-A.x, P.y-A.y };
    return Cross(AB, AP) / Length(AB);
}
const double eps = 1e-9;
int dcmp(double x) {
    if(fabs(x) < eps) return 0;
    return x<0 ? -1 : 1;
}
bool Judge_Intersection(Point A1, Point B1, Point A2, Point B2) {
    double t1 = Point_To_Line(A1, A2, B2);
    double t2 = Point_To_Line(B1, A2, B2);
    double t3 = Point_To_Line(A2, A1, B1);
    double t4 = Point_To_Line(B2, A1, B1);
    if(dcmp(t1)*dcmp(t2)<=0 && dcmp(t3)*dcmp(t4)<=0) return true;
    return false;
}

vector< int > G[N];
void Addedge(int u, int v) { G[u].PB(v), G[v].PB(u); }
int color[N];
bool dfs(int u, int col) {
    color[u] = col;
    for(int to : G[u]) {
        if(color[to]==col) return false;
        if(color[to]==0 && !dfs(to, -col)) return false;
    }
    return true;
}
bool Judge_TwoPartiteGraph(int n) {
    memset(color, 0, sizeof(color));
    for(int i=1; i<=n; ++i)
        if(color[i]==0) {
            if(!dfs(i, 1)) return false;
        }
    return true;
}

int w, p, s[N];
Point well[N], pipe[N];
int main()
{
    scanf("%d%d", &w, &p);
    rep(i,1,w) scanf("%lf%lf", &well[i].x, &well[i].y);
    rep(i,1,p) scanf("%d%lf%lf", &s[i], &pipe[i].x, &pipe[i].y);
    rep(i,1,p) rep(j,i+1,p) if(s[i]!=s[j]) {
        if(Judge_Intersection(well[s[i]], pipe[i], well[s[j]], pipe[j])) {
            Addedge(i, j),  Addedge(j, i);
        }
    }
    if(Judge_TwoPartiteGraph(p)) puts("possible");
    else  puts("impossible");

    return 0;
}
posted @ 2018-05-10 15:13  v9fly  阅读(112)  评论(0编辑  收藏  举报