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;
}