structpoint { ll x, y; }; ll dist(point a, point b){ return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y); }
namespace graph { structedge { int to, next; } e[N*N]; int head[N], ecnt = 1; int vis[N], dfn; int match[N]; boolfind(int x); voidadd_edge(int a, int b); } usingnamespace graph;
int n; point a[N], lm, b[N];
#define l(i) (i) #define r(i) (i+n)
intmain() { cin >> n; for(int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y; cin >> lm.x >> lm.y; for(int i = 1; i <= n; i++) cin >> b[i].x >> b[i].y; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) if(dist(a[i], b[j]) <= dist(a[i], lm)) add_edge(l(i), r(j)); int cnt = 0; for(int i = 1; i <= n; i++) cnt += (dfn++, find(l(i))); if(cnt == n) cout << "POSSIBLE\n"; else cout << "IMPOSSIBLE\n"; }
namespace graph { boolfind(int x) { if(vis[x] == dfn) returnfalse; vis[x] = dfn; for(int i = head[x]; i; i = e[i].next) { if(!match[e[i].to] orfind(match[e[i].to])) { match[e[i].to] = x; returntrue; } } returnfalse; } voidadd_edge(int a, int b) { e[++ecnt] = {b, head[a]}; head[a] = ecnt; } }