zoj 3460 Missile

Missile


Time Limit: 2 Seconds      Memory Limit: 65536 KB


You control N missile launching towers. Every tower has enough missiles, but for each tower only one missile can be launch at the same time. Before the launching, every missile need T1 seconds to leave the tower. Assume that all the missiles have the same speed V, and it would fly along the shortest path to the target. You can just consider the horizontal distance and ignore the height. You can consider the time equal to distance / V (minutes). The missile can immediately destroy the target when it reached. Besides, for the same tower, after launching a missile, it need T2 minutes to prepare for the next one.

Now, give you the coordinate position of N missile launching towers and M targets, T1, T2 and V, you should find the minimum minutes to destroy all the targets.

Input

The input will consist of about 10 cases. The first line of each case contains five positive integer numbers N, M, T1, T2 and V, decribed as above. The next M lines contains two integer numbers indicating the coordinate of M targets. The continueing N lines contains two integer numbers indicating the coordinate of N towers.
To all the
cases, 1 ≤ N ≤ 50, 1 ≤ M ≤ 50
The absolute value of all the
coordinates will not exceed 10000, T1,
T2, V will not exceed 2000.

Output

For each case, the output is only one line containing only one real number
with six digits precision (after a decimal point) indicating the minimum minutes
to destroy all the targets.

Sample Input

3 3 30 20 1
0 0
0 50
50 0
50 50
0 1000
1000 0

Sample Output

91.500000
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#define INF 0x3f3f3f3f
#define maxn 5000
#define maxm 500000
using namespace std;

int head[maxn], cur[maxn], cnt;
int dist[maxn], vis[maxn];
struct node {
	int u, v, cap, flow, next;
};

struct NODE{
	double x, y;
};

node edge[maxm];
NODE tower[60];
NODE target[60];
int N, M;
double T1, T2, V;
double map[60][60];
double Time[3000][60];

double change(NODE a, NODE b){
	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

void init(){
	cnt = 0;
	memset(head, -1, sizeof(head));
}

void add(int u, int v, int w){
	node E1 = {u, v, w, 0, head[u]};
	edge[cnt] = E1;
	head[u] = cnt++;
	node E2 = {v, u, 0, 0, head[v]};
	edge[cnt] = E2;
	head[v] = cnt++;
}

void getmap(double max_min){
	int i, j;
	for(i = 1; i <= N * M; ++i)
		add(0, i, 1);
	for(i = N * M + 1; i <= N * M + M; ++i)
		add(i, N * M + M + 1, 1);
	for(i = 1; i <= N * M; ++i)
		for(j = 1; j <= M; ++j)
			if(Time[i][j] <= max_min)
				add(i, j + N * M, 1);
}

bool BFS(int st, int ed){
    queue<int>q;
    memset(vis, 0, sizeof(vis));
    memset(dist, -1, sizeof(dist));
    q.push(st);
    vis[st] = 1;
    dist[st] = 0;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int i = head[u]; i != -1; i = edge[i].next){
            node E = edge[i];
            if(!vis[E.v] && E.cap > E.flow){
                vis[E.v] = 1;
                dist[E.v] = dist[u] + 1;
                if(E.v == ed) return true;
                q.push(E.v);
            }
        }
    }
    return false;
}  

int DFS(int x, int ed, int a){
    if(a == 0 || x == ed)
        return a;
    int flow = 0, f;
    for(int &i = cur[x]; i != -1; i =edge[i].next){
        node &E = edge[i];
        if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){
            E.flow += f;
            edge[i ^ 1].flow -= f;
            flow += f;
            a -= f;
            if(a == 0) break;
        }
    }
    return flow;
}  

int maxflow (int st, int ed){
    int flowsum  = 0;
    while(BFS(st, ed)){
        memcpy(cur, head, sizeof(head));
        flowsum += DFS(st, ed, INF);
    }
    return flowsum;
}  

int main (){
	while(scanf("%d%d%lf%lf%lf", &N, &M, &T1, &T2, &V) != EOF){
		T1 = T1 / 60;
		int i, j, k;
		for(j = 1; j <= M; ++j)
			scanf("%lf%lf", &target[j].x, &target[j].y);
		for(i = 1; i <= N; ++i)
			scanf("%lf%lf", &tower[i].x, &tower[i].y);
		for(i = 1; i <= N; ++i)
			for(j = 1; j <= M; ++j)
				map[i][j] = change(tower[i], target[j]);
		for(i = 1; i <= N; ++i)
			for(k = 1; k <= M; ++k){
				for(j = 1; j <= M; ++j)
				Time[(i - 1) * M + k][j] = T1 * k + T2 * (k - 1) + map[i][j] / V;
			}
		double l = 0.0, r = 200000000000.0, mid;
		while(r - l >= 1e-8){
			mid = (l + r) / 2;
			init();
			getmap(mid);
			if(maxflow(0, N * M + M + 1) >= M)
				r = mid;
			else
				l = mid;
		}
		printf("%.6lf\n", r);
	}
	return 0;
}

  

时间: 2024-10-11 00:33:42

zoj 3460 Missile的相关文章

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

解题思路: 把每一个可发射导弹的时间看成一个发射装置,总共n * m个,然后二分答案 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <string.h> #include <vector> #include <queue> #include <mat

zoj 3460 二分+二分图匹配

不错的思想 1 /* 2 大致题意: 3 4 用n个导弹发射塔攻击m个目标.每个发射架在某个时刻只能为 5 一颗导弹服务,发射一颗导弹需要准备t1的时间,一颗导弹从发 6 射到击中目标的时间与目标到发射架的距离有关.每颗导弹发 7 射完成之后发射架需要t2的时间进入下个发射流程.现在问 8 最少需要多少时间可以击毁所有m个目标. 9 10 11 大致思路: 12 二分枚举这个最大时间的最小值,每次按照这个枚举的时间构出 13 二分图,求最大匹配来判定枚举值是否符合要求. 14 15 注意单位,T

zoj3460

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3460 Missile Time Limit: 2 Seconds      Memory Limit: 65536 KB You control N missile launching towers. Every tower has enough missiles, but for each tower only one missile can be launch at

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an

zoj 2156 - Charlie&#39;s Change

题目:钱数拼凑,面值为1,5,10,25,求组成n面值的最大钱币数. 分析:dp,01背包.需要进行二进制拆分,否则TLE,利用数组记录每种硬币的个数,方便更新. 写了一个 多重背包的 O(NV)反而没有拆分快.囧,最后利用了状态压缩优化 90ms: 把 1 cents 的最后处理,其他都除以5,状态就少了5倍了. 说明:貌似我的比大黄的快.(2011-09-26 12:49). #include <stdio.h> #include <stdlib.h> #include <

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

ZOJ 3607 Lazier Salesgirl (贪心)

Lazier Salesgirl Time Limit: 2 Seconds      Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer a piece of bread for price pi. But she is so lazy

ZOJ - 2243 - Binary Search Heap Construction

先上题目: Binary Search Heap Construction Time Limit: 5 Seconds      Memory Limit: 32768 KB Read the statement of problem G for the definitions concerning trees. In the following we define the basic terminology of heaps. A heap is a tree whose internal n

ZOJ 2859 二维线段树

思路:自己写的第二发二维线段树1A,哈哈,看来对二维的push操作比较了解了:但是还没遇到在两个线段树中同时进行push操作的,其实这题我是想在x维和y维同时进行push操作的,但是想了好久不会,然后看到这题又给出10秒,然后想想在x维线段直接单点查询肯定也过了,然后在第二维就只有pushup操作,在第一维线段树没有pushup操作.要是在第一维也有pushup操作的话,那就不用单点查询那么慢了.不过也A了,想找题即在二维同时进行pushup和pushdown操作的. #include<iost