Links: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3726
Algorithm See: http://fanhq666.blog.163.com/blog/static/8194342620120304463580/
Test instructions: There are n points on the board, and now two people take turns removing a child, each of which is removed from the last sub-Manhattan distance less than L. The last person who cannot be removed loses.
Analysis: points with a distance less than L are connected to the edge. If a connected block is not a complete match, the initiator must be able to go to a non-matching point, and then can not remove the child, if the next to remove the child, then there is a new match, now is a complete match.
Code:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include < string> #include <vector> #include <queue> #include <cmath> #include <stack> #include <set > #include <map> #define INF 0x3f3f3f3f#define Mn 400#define Mm 200005#define mod 1000000007#define CLR (A, B) Memset ((a), (b), sizeof ((a))) #define CPY (a) memcpy ((a), (b), sizeof ((a))) #pragma comment (linker, "/stack : 102400000,102400000 ") #define UL u<<1#define ur (u<<1) |1using namespace Std;typedef long Long ll;struct edge {int v,next;} E[mm];struct point {int x, y;} P[mn];int Dis (point a,point b) {return abs (a.x-b.x) +abs (A.Y-B.Y);} int tot,head[mn];void Addedge (int u,int v) {e[tot].v=v; E[tot].next=head[u]; head[u]=tot++;} int pre[mn];int findpre (int x) {return x==pre[x]?pre[x]:p re[x]=findpre (pre[pre[x]]);} void ol (int a,int b) {a=findpre (a); B=findpre (b); if (a!=b) pre[a]=b;} int N,lk[mn],vis[mn],mark[mn],match[mn],ne[mn];int LCA(int x,int y) {static int t=0;t++; while (1) {if (x!=-1) {x=findpre (x); if (vis[x]==t) return x; vis[x]=t; if (match[x]!=-1) x=ne[match[x]]; else X=-1; } swap (x, y); }}queue<int> q;void Group (int a,int p) {while (a!=p) {int b=match[a],c=ne[b]; if (Findpre (c)!=p) ne[c]=b; if (mark[b]==2) Mark[b]=1,q.push (b); if (mark[c]==2) Mark[c]=1,q.push (c); OL (A, b), OL (B,C); A=c; }}void (int s) {for (int i=0;i<=n;i++) {ne[i]=-1; Pre[i]=i; mark[i]=0; Vis[i]=-1; } mark[s]=1; while (!q.empty ()) Q.pop (); Q.push (s); while ((!q.empty ()) &&match[s]==-1) {int U=q.front (); Q.pop (); for (int i=head[u];~i;i=e[i].next) {int v=e[i].v; if (match[u]==v| | Findpre (U) ==findpre (v) | | mark[v]==2) continue; if (mark[v]==1) {int R=lca (U,V); if (Findpre (U)!=r) Ne[u]=v; if (Findpre (v)!=r) Ne[v]=u; Group (U,R); Group (V,R); } else if (match[v]==-1) {ne[v]=u; for (int x=v;~x;) {int y=ne[x]; int mv=match[y]; Match[x]=y,match[y]=x; X=MV; } break; } else {ne[v]=u; Q.push (Match[v]); Mark[match[v]]=1; mark[v]=2; }}}}void init () {tot=0; CLR (head,-1);} int main () {while (~SCANF ("%d", &n)) {int l;init (); for (int i=1;i<=n;i++) scanf ("%d%d", &p[i].x,&p[i].y); scanf ("%d", &l); for (int i=1;i<n;i++) {for (int j=i+1;j<=n;j++) {if (DIS (p[i],p[j]) <=l) { Addedge (I,J); Addedge (J,i); }}} for (int i=1;i<=n;i++) Match[i]=-1; for (int i=1;i<=n;i++) {if (match[i]==-1) (i); } int ans=0; for (int i=1;i<=n;i++) {if (match[i]!=-1) ans++; } if (ans==n) {printf ("yes\n"); } else printf ("no\n"); } return 0;}
zoj3316 "General graph Max match with Flower tree Blossom"