ZOJ 3460 Missile(二分+ 二分图匹配)

解题思路:

把每一个可发射导弹的时间看成一个发射装置,总共n * m个,然后二分答案#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>#include <string.h>#include <vector>#include <queue>#include <math.h>#include <set>#include <map>#include <stack>#define LL long long#define FOR(i, x, y) for(int i=x;i<=y;i++)using namespace std;const double eps = 1e-8;const int MAXN = 2500 + 10;int vis[MAXN];vector<int>G[60];int match[MAXN];double t[MAXN][60];struct Point{int x, y;}A[MAXN], B[MAXN];int n, m;double t1, t2, v;double dis(Point A, Point B){double x = A.x – B.x;double y = A.y – B.y;return sqrt(x * x + y * y);}int path(int u){int sz = G[u].size();for(int i=0;i<sz;i++){int v = G[u][i];if(!vis[v]){vis[v] = 1;if(match[v] == -1 || path(match[v])){match[v] = u;return 1;}}}return 0;}int MaxMatch(){int res = 0;memset(match, -1, sizeof(match));for(int i=0;i<m;i++){memset(vis, 0, sizeof(vis));res += path(i);}return res;}double d[MAXN][60];int main(){while(scanf("%d%d%lf%lf%lf", &n, &m, &t1, &t2, &v)!=EOF){t1 /= 60;FOR(i, 0, m-1) scanf("%d%d", &B[i].x, &B[i].y);FOR(i, 0, n-1) scanf("%d%d", &A[i].x, &A[i].y);for(int i=0;i<n;i++){for(int j=0;j<m;j++)d[i][j] = dis(A[i], B[j]);}FOR(k, 0, m-1){FOR(i, 0, n-1){FOR(j, 0, m-1){t[i*m+k][j] = k * t2 +(k+1) * t1 + d[i][j] / v;}}}double l = 0, r = 2000000000000.0;while(r – l >= eps){double mid = (l + r) * 0.5;for(int i=0;i<60;i++) G[i].clear();for(int i=0;i<n*m;i++){for(int j=0;j<m;j++){if(t[i][j] <= mid) G[j].push_back(i);}}if(MaxMatch() == m){r = mid;}else l = mid;}printf("%.6lf\n", r);}return 0;}

,有多远,走多远,把足迹连成生命线。

ZOJ 3460 Missile(二分+ 二分图匹配)

相关文章:

你感兴趣的文章:

标签云: