POJ 2536 Gopher II
二分图的最大匹配
地鼠内部和地鼠洞内部都是没有边相连的,那么就可以看成一个二分图。地鼠如果可以跑到那个地鼠洞,就连一条边,然后跑二分图的最大匹配,最后地鼠的数量减去最大匹配数就是答案。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int MAXN=505; int nx,ny; int g[MAXN][MAXN]; int cx[MAXN],cy[MAXN]; int mk[MAXN]; int n; double s,v; double H=1e-8; struct P { double x,y; } M[MAXN],D[MAXN]; int path(int u) { for(int v=0; v<ny; v++) { if(g[u][v]&&!mk[v]) { mk[v]=1; if(cy[v]==-1||path(cy[v])) { cx[u]=v; cy[v]=u; return 1; } } } return 0; } int MaxMatch() { int res=0; memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); for(int i=0; i<nx; i++) { if(cx[i]==-1) { memset(mk,0,sizeof(mk)); res=res+path(i); } } return res; } bool ok(const P&a,const P&b) { if(s*v-sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))>=H) return 1; return 0; } int main() { int i,j; while(~scanf("%d%d%lf%lf",&nx,&ny,&s,&v)) { memset(g,0,sizeof(g)); for(i=0; i<nx; i++) scanf("%lf%lf",&M[i].x,&M[i].y); for(i=0; i<ny; i++) scanf("%lf%lf",&D[i].x,&D[i].y); for(i=0; i<nx; i++) for(j=0; j<ny; j++) if(ok(M[i],D[j])) g[i][j]=1; printf("%d\n",nx-MaxMatch()); } return 0; }