zoukankan      html  css  js  c++  java
  • 【计算几何】【二分图判定】Gym

    题意:有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;
    }
  • 相关阅读:
    HTTP状态码
    CentOS 7 上安装vim(默认未安装)
    yum安装提示Another app is currently holding the yum lock; waiting for it to exit...
    CentOS 7 安装telnet服务
    shell编程
    shell基础
    ssh相关命令
    ssh无密码连接
    centos7小命令
    日志管理
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7700403.html
Copyright © 2011-2022 走看看