http://poj.org/problem?id=1034
题意:
猎人和狗一起出去,狗的速度是猎人的两倍,给出猎人的路径坐标,除了这些坐标外,地图上还有一些有趣的点,而我们的狗,就是要尽量去多的有趣的点。前提是在猎人到达一个点的时候,狗必须也正好到。
思路:
二分图匹配,猎人的路径在一边,有趣的点在另一边,我们就是求一个最大匹配。
1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 8 struct node 9 { 10 int x, y; 11 }; 12 13 node Bob[105], Dog[105]; 14 int g[105][105]; 15 int vis[105]; 16 int match[105]; 17 int path[105]; 18 int n, m; 19 20 21 double dis(int x1, int y1, int x2, int y2) 22 { 23 return sqrt((double)(x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)); 24 } 25 26 27 int dfs(int x) 28 { 29 for (int i = 0; i < m; i++) 30 { 31 if (g[x][i] && !vis[i]) 32 { 33 vis[i] = 1; 34 if (match[i]==-1 || dfs(match[i])) 35 { 36 match[i] = x; 37 return 1; 38 } 39 } 40 } 41 return 0; 42 } 43 44 int main() 45 { 46 //freopen("D:\txt.txt", "r", stdin); 47 while (cin >> n >> m) 48 { 49 for (int i = 0; i < n; i++) 50 cin >> Bob[i].x >> Bob[i].y; 51 for (int i = 0; i < m; i++) 52 cin >> Dog[i].x >> Dog[i].y; 53 54 memset(g, 0, sizeof(g)); 55 memset(match, -1, sizeof(match)); 56 57 for (int i = 0; i < n - 1; i++) 58 for (int j = 0; j < m; j++) 59 { 60 double d1 = dis(Bob[i].x, Bob[i].y, Bob[i + 1].x, Bob[i + 1].y); 61 double d2 = dis(Bob[i].x, Bob[i].y, Dog[j].x, Dog[j].y); 62 double d3 = dis(Bob[i + 1].x, Bob[i + 1].y, Dog[j].x, Dog[j].y); 63 if (d2 + d3 - 2 * d1 <= 0) 64 g[i][j] = 1; 65 } 66 int ans = 0; 67 for (int i = 0; i < n; i++) 68 { 69 memset(vis, 0, sizeof(vis)); 70 if(dfs(i)) ans++; 71 } 72 cout << ans + n << endl; 73 74 memset(path, -1, sizeof(path)); 75 for (int i = 0; i < m; i++) 76 { 77 if (match[i] != -1) 78 path[match[i]] = i; 79 } 80 for (int i = 0; i < n - 1; i++) 81 { 82 cout << Bob[i].x << " " << Bob[i].y << " "; 83 if (path[i] != -1) 84 cout << Dog[path[i]].x << " " << Dog[path[i]].y << " "; 85 } 86 cout << Bob[n - 1].x << " " << Bob[n - 1].y << endl; 87 } 88 return 0; 89 }