题目链接:
id=2536
题目大意:
有N仅仅鼹鼠和M个洞穴,假设鼹鼠在S秒内不可以跑到洞穴,就会被老鹰捉住吃掉。
鼹鼠跑的速度为V米/秒。
已知一个洞穴仅仅能容纳一仅仅鼹鼠。给你鼹鼠和洞穴的坐标,那么问题来了:问最少有多少仅仅鼹鼠被老鹰捉住
吃掉。
思路:
建立一个二分图,一边为鼹鼠,还有一边为洞穴枚举求出每仅仅鼹鼠到各个洞穴的距离,把可以在S秒内跑到该
洞穴(距离<=S*V)的进行连边。建好图后用匈牙利算法求出最多有多少仅仅鼹鼠可以幸免于难( MaxMatch() ),
那么剩下的N - MaxMatch()就是最少有多少仅仅鼹鼠被老鹰捉住吃掉。
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int N,M,S,V; struct Node { double x; double y; }PA[330],PB[330]; int Map[330][330]; bool Mask[330]; int cx[330],cy[330]; int FindPath(int u) { for(int i = 1; i <= M; ++i) { if(Map[u][i] && !Mask[i]) { Mask[i] = 1; if(cy[i] == -1 || FindPath(cy[i])) { cy[i] = u; cx[u] = i; return 1; } } } return 0; } int MaxMatch() { int res = 0; for(int i = 1; i <= N; ++i) cx[i] = -1; for(int i = 1; i <= M; ++i) cy[i] = -1; for(int i = 1; i <= N; ++i) { if(cx[i] == -1) { for(int j = 1; j <= M; ++j) Mask[j] = 0; res += FindPath(i); } } return res; } int main() { while(~scanf("%d%d%d%d",&N,&M,&S,&V)) { for(int i = 1; i <= N; ++i) scanf("%lf%lf",&PA[i].x,&PA[i].y); for(int i = 1; i <= M; ++i) scanf("%lf%lf",&PB[i].x,&PB[i].y); memset(Map,0,sizeof(Map)); for(int i = 1; i <= N; ++i) { for(int j = 1; j <= M; ++j) { double x = PA[i].x - PB[j].x; double y = PA[i].y - PB[j].y; if(x*x+y*y <= S*V*S*V) Map[i][j] = 1; } } printf("%d ",N-MaxMatch()); } return 0; }