题意:有n个水井,每个水井发出一些管线(都是线段),然后每条管线上最多只有一个水井。所有从不同的水井发出的管线的相交点都是清洁点(不存在清洁点是大于两条管线点的交点)。你需要在某些管线上放出一些机器人,它们会清洁所有该条管线上的清洁点。但是两条相交的管线不能同时放有机器人。问你是否存在一种可行的放机器人的方案。

将管线当成点,清洁点当作边(需要计算几何判断线段规范相交,具体看代码),建图,看看是否是二分图即可。

因为二分图显然可以选择一些点,使得每条边恰好被选择一个点(只选择X部或者只选择Y部的点就是一个合法解)。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
struct Point{
ll x,y;
Point(const ll &x,const ll &y){
this->x=x;
this->y=y;
}
Point(){}
void read(){
scanf("%I64d%I64d",&x,&y);
}
}wells[1005];
typedef Point Vector;
Vector operator - (const Point &a,const Point &b){
return Vector(a.x-b.x,a.y-b.y);
}
ll Cross(const Vector &a,const Vector &b){
return a.x*b.y-a.y*b.x;
}
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
return c1*c2<=0 && c3*c4<=0;
}
int n,m;
struct PIPE{
int wid;
Point End;
PIPE(const int &wid,const Point &End){
this->wid=wid;
this->End=End;
}
PIPE(){}
PIPE(const int &wid,const ll &x,const ll &y){
this->wid=wid;
End.x=x;
End.y=y;
}
void read(){
scanf("%d",&wid);
End.read();
}
}pipes[1005];
bool cmp(const PIPE &a,const PIPE &b){
return a.wid<b.wid;
}
int v[2000005],first[1005],e,next[2000005];
void AddEdge(int U,int V){
v[++e]=V;
next[e]=first[U];
first[U]=e;
}
int col[1005];
bool dfs(int U,bool now)
{
for(int i=first[U];i;i=next[i]){
if(col[v[i]]==-1){
col[v[i]]=(now^1);
if(!dfs(v[i],now^1)){
return 0;
}
}
else if(col[v[i]]==col[U]){
return 0;
}
}
return 1;
}
int main(){
// freopen("c.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
wells[i].read();
}
for(int i=1;i<=m;++i){
pipes[i].read();
}
sort(pipes+1,pipes+m+1,cmp);
int sta;
for(int i=1;i<=m;++i){
if(pipes[i].wid!=pipes[i-1].wid){
sta=i;
}
if(pipes[i].wid!=pipes[i+1].wid){
for(int j=sta;j<=i;++j){
for(int k=i+1;k<=m;++k){
if(SegmentProperIntersection(wells[pipes[j].wid],pipes[j].End,wells[pipes[k].wid],pipes[k].End)){
AddEdge(j,k);
AddEdge(k,j);
}
}
}
}
}
memset(col,-1,sizeof(col));
for(int i=1;i<=m;++i){
if(col[i]==-1){
col[i]=0;
if(!dfs(i,0)){
puts("impossible");
return 0;
}
}
}
puts("possible");
return 0;
}

【计算几何】【二分图判定】Gym - 101485C - Cleaning Pipes的更多相关文章

  1. CF687A. NP-Hard Problem[二分图判定]

    A. NP-Hard Problem time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. COJ 0578 4019二分图判定

    4019二分图判定 难度级别: B: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 给定一个具有n个顶点(顶点编号为0,1,… ...

  3. hdoj 3478 Catch(二分图判定+并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478 思路分析:该问题需要求是否存在某一个时刻,thief可能存在图中没一个点:将该问题转换为图论问题 ...

  4. UVA 11080 - Place the Guards(二分图判定)

    UVA 11080 - Place the Guards 题目链接 题意:一些城市.之间有道路相连,如今要安放警卫,警卫能看守到当前点周围的边,一条边仅仅能有一个警卫看守,问是否有方案,假设有最少放几 ...

  5. poj2942 Knights of the Round Table,无向图点双联通,二分图判定

    点击打开链接 无向图点双联通.二分图判定 <span style="font-size:18px;">#include <cstdio> #include ...

  6. HDU2444(KB10-B 二分图判定+最大匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  7. DFS的运用(二分图判定、无向图的割顶和桥,双连通分量,有向图的强连通分量)

    一.dfs框架: vector<int>G[maxn]; //存图 int vis[maxn]; //节点访问标记 void dfs(int u) { vis[u] = ; PREVISI ...

  8. bzoj4427【Nwerc2015】Cleaning Pipes清理管道

    题目描述 Linköping有一个相当复杂的水资源运输系统.在Linköping周围的出水点有一些水井.这些水通过管道输送到其它地点.每条管道是从某一个水井到城市的某个位置的直线管道. 所有管道在地下 ...

  9. UVa 11396 爪分解(二分图判定)

    https://vjudge.net/problem/UVA-11396 题意: 给出n个结点的简单无向图,每个点的度数均为3.你的任务是判断能否把它分解成若干爪.每条边必须属于一个爪,但同一个点可以 ...

随机推荐

  1. NYOJ 1012 RMQ with Shifts (线段树)

    题目链接 In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each q ...

  2. python模块之imghdr检测图片类型

    1. imghdr是什么 imghdr是一个用来检测图片类型的模块,传递给它的可以是一个文件对象,也可以是一个字节流. 能够支持的图片格式: 2. 如何使用 提供了一个api叫做imghdr.what ...

  3. npm的常用命令

    npm install <name>安装nodejs的依赖包 例如npm install express 就会默认安装express的最新版本,也可以通过在后面加版本号的方式安装指定版本, ...

  4. php常用函数——数组函数

    php常用函数——数组函数

  5. docker之安装和基本使用(一)

    前言 开始折腾docker. 主要概念 容器:独立运行的一个或一组应用,与其他应用完全独立. 镜像:用于创建 Docker容器的模板. 仓库:用于收纳镜像文件,可以理解为代码控制中的代码仓库 注意: ...

  6. python基础之常用的高阶函数

    前言 高阶函数指的是能接收函数作为参数的函数或类:python中有一些内置的高阶函数,在某些场合使用可以提高代码的效率. map() map函数可以把一个迭代对象转换成另一个可迭代对象,不过在pyth ...

  7. offset宏的讲解【转】

    转自:http://blog.csdn.net/tigerjibo/article/details/8299584 1.offset宏讲解 #define offsetof(TYPE, MEMBER) ...

  8. 121.Best Time to Buy and Sell Stock---dp

    题目链接:https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/ 题目大意:给出一串数组,找到差值最大的差 ...

  9. Ural Sport Programming Championship 2015

    Ural Sport Programming Championship 2015 A - The First Day at School 题目描述:给出课程安排,打印一个课程表. solution 暴 ...

  10. acm专题---动态规划

    题目来源:http://hihocoder.com/problemset/problem/1400?sid=983096 #1400 : Composition 时间限制:10000ms 单点时限:1 ...