地鼠的困境
2012-05-25 16:30
148 查看
【金凌模拟试题】:地鼠的困境Time Limit:1000MS Memory Limit:65536KTotal Submit:40 Accepted:16Description地鼠家族面临着一个新的威胁——猎食者。 地鼠家族一共有N个地鼠和M个鼠洞,每个都位于不同的(x, y)坐标中。假如有地鼠在发觉危险以后s秒内都没有回到鼠洞里的话,就可能成为老鹰的食物。当然了,一个鼠洞只能拯救一只地鼠的命运,所有地鼠都以相等的速度v移动。地鼠家族需要设计一种策略,使得老鹰来时,易受攻击的地鼠数量最少。 Input本题有多组数据。第1行为测试数据组数T(T<=50)。 对于每组数据,第一行4个整数n, m, s和v(n, m <= 100)。以后n行为地鼠的坐标,以后m行为鼠洞的坐标。距离的单位是m,时间的单位是s,速度的单位是m/s。 Output对于每组数据输出一行,为易受攻击的地鼠的数量。Sample Input
1 2 2 5 10 1.0 1.0 2.0 2.0 100.0 100.0 20.0 20.0Sample Output
1
二分图的最大匹配
#include <iostream>using namespace std;double dist(double x1,double y1,double x2,double y2){return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);}const double eps=1e-12;//NOTES:eps#define MAXN 105#define MAXM 105struct node{ double x; double y;}gopher[MAXN],hole[MAXM];int n, m; //n为集合x个数,m为集合y个数bool graph[MAXN][MAXM];int match[MAXM];//表示元素j的与之匹配的是哪个元素i,一开始要全部初始化为n,表示和哪个都不匹配int chk[MAXM]; //表示元素i在dfs中是否被访问过bool dfs(int p) //DFS,从元素p出发寻找增广路{ int i, t; for (i = 1; i <= m; i++) { if (graph[p][i] && !chk[i]) //令i匹配p,递归搜索 { chk[i] = 1; t = match[i]; if (t == -1 || dfs(t)) { match[i] = p; return true; } } } return false;}int hungary() //匈牙利算法,返回最大匹配数{ int i, res = 0; for (i = 1; i <= m; i++) { match[i] = -1; } for (i = 1; i <= n; i++) //循环n次,每次确定一个元素被匹配 { memset(chk,false,sizeof(chk)); if (dfs(i)) //如果找到,匹配数加1 res++; } return res;}int main(){ int i, j, s, v,t; double dd; cin>>t; while(t--){ scanf("%d%d%d%d",&n,&m,&s,&v); memset(graph,false,sizeof(graph)); //注意初始化! dd = s*v*s*v; for (i = 1; i <= n; i++) { scanf("%lf%lf",&gopher[i].x,&gopher[i].y); } for (i = 1; i <= m; i++) { scanf("%lf%lf",&hole[i].x,&hole[i].y); } for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { if (dist(gopher[i].x,gopher[i].y,hole[j].x,hole[j].y) <= dd) { graph[i][j] = true; } } } printf("%d\n",n - hungary()); } return 0; }