【計算幾何】【二分圖判定】Gym - 101485C - Cleaning Pipes
阿新 • • 發佈:2017-10-20
你是 i+1 ace 機器 ble mes 方案 clu str
題意:有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