http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1882
http://poj.org/problem?id=2536
题目大意:
有n之地鼠和m个地洞,他们需要在s秒内以v秒的速度跑进洞中,否则会被鹰抓走。给定每个地鼠和洞的坐标,每个洞最多容纳一只地鼠,问最小有危险的地鼠个数。
思路:
跑回学校了~来A几题。 几个月前看的题不会做T T,现在好简单。。。
本题可以转化为二分图匹配。如果地鼠到洞的时间小于s,那么久建一条边,求出最大匹配,然后用总数减去最大匹配即可。
#include<cstdio> #include<cmath> #include<cstring> const int MAXN=200+10; int head[MAXN],len,res[MAXN]; bool vis[MAXN]; struct edge { int to,next; }e[MAXN*MAXN]; void add(int from,int to) { e[len].to=to; e[len].next=head[from]; head[from]=len++; } struct point { double x,y; }gopher[MAXN],hole[MAXN]; double getlen(double x1,double y1,double x2,double y2) { return sqrt( (x1-x2)*(x1-x2) +(y1-y2)*(y1-y2)); } bool find(int a) { for(int i=head[a];i!=-1;i=e[i].next) { int id=e[i].to; if(!vis[id]) { vis[id]=true; if(res[id]==0 || find(res[id]) ) { res[id]=a; return true; } } } return false; } int main() { int n,m; double s,v; while(~scanf("%d%d%lf%lf",&n,&m,&s,&v)) { memset(head,-1,sizeof(head)); memset(res,0,sizeof(res)); len=0; for(int i=1;i<=n;i++) scanf("%lf%lf",&gopher[i].x,&gopher[i].y); for(int i=1;i<=m;i++) scanf("%lf%lf",&hole[i].x,&hole[i].y); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { double len=getlen(gopher[i].x,gopher[i].y,hole[j].x,hole[j].y); if( len/v < s) add(i,j); } } int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(find(i)) ans++; } printf("%d\n",n-ans); } return 0; }