POJ 2536 Gopher II(二分图最大匹配)
http://poj.org/problem?id=2536
题意:
有n个地鼠和m个洞,有鹰飞来时,n个地鼠如果能在s秒从当前位置回到一个洞,就能不死,一个洞能容纳一个地鼠,它们的速度为v。求可能死的地鼠个数的最小值。
分析:
如果一个地鼠能在s秒内到达一个特定的洞,那么就在它们之间两一条无向边. 我们所建立的图是一个二分图,左边是地鼠,右边是洞.
现在我们要求的就是该图的最大匹配数.
那么可能死的地鼠个数 = n – 最大匹配数.
AC代码:
#include<cstdio> #include<cstring> #include<cmath> using namespace std; const int maxn=100+5; struct Max_Match { int n,m; bool g[maxn][maxn]; bool vis[maxn]; int left[maxn]; void init(int n,int m) { this->n=n; this->m=m; memset(g,0,sizeof(g)); memset(left,-1,sizeof(left)); } bool match(int u) { for(int v=1;v<=m;v++)if(g[u][v] && !vis[v]) { vis[v]=true; if(left[v]==-1 || match(left[v])) { left[v]=u; return true; } } return false; } int solve() { int ans=0; for(int i=1;i<=m;i++) { memset(vis,0,sizeof(vis)); if(match(i)) ans++; } return ans; } }MM; struct Point { double x,y; void read() { scanf("%lf%lf",&x,&y); } }P1[maxn],P2[maxn]; double get_dist(int i,int j) { return sqrt( (P1[i].x-P2[j].x)*(P1[i].x-P2[j].x)+(P1[i].y-P2[j].y)*(P1[i].y-P2[j].y) ); } int main() { int n,m,s,v; while(scanf("%d%d%d%d",&n,&m,&s,&v)==4) { MM.init(n,m); for(int i=1;i<=n;i++) P1[i].read(); for(int i=1;i<=m;i++) P2[i].read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(get_dist(i,j) <= s*v ) { MM.g[i][j]=true; } } printf("%d\n",n-MM.solve()); } return 0; }