POJ 2536 之 Gopher II(二分图最大匹配)
Gopher II
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 6675 | Accepted: 2732 |
Description
The gopher family, having averted the canine threat, must face a new predator.
The are n gophers and m gopher holes, each at distinct (x, y) coordinates. A hawk arrives and if a gopher does not reach a hole in s seconds it is vulnerable to being eaten. A hole can save at most one gopher. All the gophers run at the same velocity v. The gopher family needs an escape strategy that minimizes the number of vulnerable gophers.
The are n gophers and m gopher holes, each at distinct (x, y) coordinates. A hawk arrives and if a gopher does not reach a hole in s seconds it is vulnerable to being eaten. A hole can save at most one gopher. All the gophers run at the same velocity v. The gopher family needs an escape strategy that minimizes the number of vulnerable gophers.
Input
The
input contains several cases. The first line of each case contains four
positive integers less than 100: n, m, s, and v. The next n lines give
the coordinates of the gophers; the following m lines give the
coordinates of the gopher holes. All distances are in metres; all times
are in seconds; all velocities are in metres per second.
Output
Output consists of a single line for each case, giving the number of vulnerable gophers.
Sample Input
2 2 5 10 1.0 1.0 2.0 2.0 100.0 100.0 20.0 20.0
Sample Output
1
算法分析:开始的时候很脑残,想出来的算法是贪心的策略,虽然不知是否可行,
但我的贪心策略是这样的:让每一只地鼠钻进它所能到达的最远的洞,也就是说呢,
让每一只地鼠尽可能的跑远点再钻洞。在我代码实现的过程中发现很麻烦!要记录每只
地鼠到达其他洞口的距离 还要排序什么的!非常的麻烦,并且还不知道最后的结果是否正确。
后来想到了,刚学的“二分图的最大匹配算法”,这时候的算法思想是:把读入的 每只地鼠的坐标 去计算和到其它每一个洞口的“距离”
看是否在可达的范围内,若可达,证明“该地鼠” 和 “该洞口”存在关系, 对应的map[][]标记为1。剩下的dfs. (说白了就是二分
图的模板问题)。
#include <math.h> #include <stdio.h> #include <string.h> int n, m; double s, v; struct N //记录地鼠的坐标 { double x; double y; }q[200]; struct node //记录鼠洞的坐标 { double x; double y; }w[200]; int map[150][150]; int vt[150]; int link[150]; int dfs(int dd) { int i; for(i=0; i<m; i++) { if(map[dd][i]==1 && vt[i]==0 ) { vt[i]=1; if(link[i]==-1 || dfs(link[i])) { link[i]=dd; return 1; } } } return 0; } int main() { int i, j, k; double dis; double gg; while(scanf("%d %d %lf %lf", &n, &m, &s, &v)!=EOF ) { for(i=0; i<n; i++) { scanf("%lf %lf", &q[i].x, &q[i].y ); } for(i=0; i<m; i++) { scanf("%lf %lf", &w[i].x, &w[i].y ); } gg = s * v; memset(map, 0, sizeof(map)); memset(link, -1, sizeof(link)); for(i=0; i<n; i++) { for(j=0; j<m; j++) { dis = sqrt( (w[j].x-q[i].x)*(w[j].x-q[i].x) + (w[j].y-q[i].y)*(w[j].y-q[i].y) ); if(dis<=gg) { map[i][j] = 1; } } } int cnt=0; for(i=0; i<n; i++) { memset(vt, 0, sizeof(vt)); cnt+=dfs(i); } printf("%d\n", n-cnt ); } return 0; }