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

题意:用N个导弹发射塔攻击M个目标。每个导弹发射塔只能同时为一颗导弹服务,发射一颗导弹后需要T1(这里用的是秒)的时间才能离开当前的导弹发射塔,一颗导弹从发射到击中目标的时间与目标到发射塔的距离有关(直线距离),每颗导弹发射完成之后发射塔需要T2的时间准备下一个。现在给出N个导弹发射塔和M个目标的位置坐标以及T1,T2,V,问用这N个导弹发射塔最少需要多少时间可以击毁所有M个目标。

具体实现

一:对每一个导弹发射器,它击中一个目标共有M种情况:分别为在该发射塔第一次发射、第二次发射、第三次发射...一直到第M次发射。因此我们可以把每一个导弹发射塔拆分成M个发射塔,它们与同一个目标的距离是一样的,唯一不同是T1、T2的花销占时不一样。

二:这样的话我们就得到了N*M个点发射器到 M个目标的映射,所表示的关系是当前发射塔击中目标的耗时。

三:设立超级源点0,超级汇点 N * M + M + 1。

四:超级源点到每个发射塔(拆分后的)引一条容量为1的边,每个目标到超级汇点引一条容量为1的边,按若小于当前查询时间的关系(同匹配建边)建边容量为1。

然后跑最大流,判断最大流是否为M。 接着二分查找。

以上解析来自会长大大:http://blog.csdn.net/hpuhjh/article/details/47334625

太弱了  这道题自己建不出来图,

//#include<stdio.h>
//#include<string.h>
//#include<math.h>
//#include<queue>
//#include<stack>
//#include<algorithm>
//#define MAX 110
//#define DD double
//#define INF 0x7fffff
//#define MAXM 500100
//using namespace std;
//struct node
//{
// int from,to,cap,flow,next;
//}edge[MAXM];
//int dis[MAX],vis[MAX];
//int cur[MAX];
//int ans,head[MAX];
//int n,m;
//DD t1,t2,v;
////DD toalx[MAX],toaly[MAX],towrx[MAX],towry[MAX];
//struct record
//{
// DD x,y;
//};
//DD time[3000][MAX];
//DD map[MAX][MAX];
//void init()
//{
// ans=0;
// memset(head,-1,sizeof(head));
//}
//void add(int u,int v,int w)
//{
// edge[ans]={u,v,w,0,head[u]};
// head[u]=ans++;
// edge[ans]={v,u,0,0,head[v]};
// head[v]=ans++;
//}
//DD dist(record a,record b)
//{
// return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
//}
//record towr[MAX];
//record toal[MAX];
//void input()
//{
// int i,j,k;
//
// for(i=1;i<=m;i++)
// scanf("%lf%lf",&toal[i].x,&toal[i].y);
// for(i=1;i<=n;i++)
// scanf("%lf%lf",&towr[i].x,&towr[i].y);
// for(i=1;i<=n;i++)
// for(j=1;j<=m;j++)
// map[i][j]=dist(towr[i],toal[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;
//}
//void getmap(double Max)
//{
// 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)
// add(i,j+n*m,1);
// }
// }
//}
//
//
//int bfs(int beg,int end)
//{
// queue<int>q;
// memset(vis,0,sizeof(vis));
// memset(dis,-1,sizeof(dis));
// while(!q.empty()) q.pop();
// vis[beg]=1;
// dis[beg]=0;
// q.push(beg);
// 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.to]&&E.cap>E.flow)
// {
// dis[E.to]=dis[u]+1;
// vis[E.to]=1;
// if(E.to==end) return 1;
// q.push(E.to);
// }
// }
// }
// return 0;
//}
//int dfs(int x,int a,int end)
//{
// if(x==end||a==0)
// return a;
// int flow=0,f;
// for(int& i=cur[x];i!=-1;i=edge[i].next)
// {
// node& E=edge[i];
// if(dis[E.to]==dis[x]+1&&(f=dfs(E.to,min(a,E.cap-E.flow),end))>0)
// {
// E.flow+=f;
// edge[i^1].flow-=f;
// flow+=f;
// a-=f;
// if(a==0) break;
// }
// }
// return flow;
//}
//int maxflow(int beg,int end)
//{
// int flow=0;
// while(bfs(beg,end))
// {
// memcpy(cur,head,sizeof(head));
// flow+=dfs(beg,INF,end);
// }
// return flow;
//}
//int main()
//{
// int t;
// while(scanf("%d%d%lf%lf%lf",&n,&m,&t1,&t2,&v)!=EOF)
// {
// t1=t1/60;
// input();
// 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;
//} #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;//t1给的单位是秒 要转换为分
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]);
//map[][]表示第i个塔到j个目标的距离
for(i = 1; i <= N; ++i)
for(k = 1; k <= M; ++k)//k表示的是发射第k个导弹
{
for(j = 1; j <= M; ++j)
Time[(i - 1) * M + k][j] = T1 * k + T2 * (k - 1) + map[i][j] / V;
//Time[][]数组表示从第i个塔依次发射炮弹到每个目标所分别需要的时间
}
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;
}
  

  

zoj 3460 Missile【经典建图&&二分】的更多相关文章

  1. hdoj--5093--Battle ships(二分图经典建图)

    Battle ships Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  2. poj--1149--PIGS(最大流经典建图)

    PIGS Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Submit Status D ...

  3. BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图

    这道逼题!感受到了数学对我的深深恶意(#‵′).... 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB S ...

  4. 【ARC069F】Flags 2-sat+线段树优化建图+二分

    Description ​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ​ 第一行一个整数 N. ​ 接下来 N 行每行两个整数 xi, ...

  5. POJ 2226 最小点覆盖(经典建图)

    Muddy Fields Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8881   Accepted: 3300 Desc ...

  6. hdu 4185 Oil Skimming(二分图匹配 经典建图+匈牙利模板)

    Problem Description Thanks to a certain "green" resources company, there is a new profitab ...

  7. 2-sat——poj3678经典建图

    比较经典的建图,详见进阶指南 2-sat一般要用到tarjan来求强连通分量 /*2-sat要加的是具有强制关系的边*/ #include<iostream> #include<cs ...

  8. 网络流--最大流--POJ 2139(超级源汇+拆点建图+二分+Floyd)

    Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the ...

  9. hdu4560 不错的建图,二分最大流

    题意: 我是歌手 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Subm ...

随机推荐

  1. VC项目配置基础以及快捷键(收藏)

    来自http://blog.csdn.net/phunxm/article/details/5082488 一.IDE基础配置 1.字体 VC6中“Tools→Options→Format→Font” ...

  2. 【Selenium】自动化调试后C盘越来越大

    在本机调试了一段时间自动化脚本后发现C盘占用越来越大,增长速度比较明显 通过360等工具清理系统垃圾表明并不好使 最后在系统临时文件中看到大量因为调试或不正常结束而Driver而产生的临时文件 具体方 ...

  3. 开发错误日志之FTP协议传输文件问题

    从开发端用FTP协议向服务器(Linux系统)传输文件时,cat -A查询文件内容中行尾会有^M出现. 解决方案:改用SFTP协议上传文件.

  4. IDEA 使用 SVN的一个注意点

    IDEA是调用SVN.EXE来实现相关版本管理功能的,所以必须要安装visualSVN,然后再使用相关功能!

  5. SSO(转)

    一.介绍       主站下有多个子系统,每次登录主系统,跳转到子系统时,又需要重新登录: 子系统与主系统都有各自的用户信息表:各个系统的用户角色.权限也各不相同: 二.目的       每次登录主系 ...

  6. xcode5编译过的xib 如何在xcode4.6下打开

    IOS7一出来,对应的xcode版本变成了5了,这次xcode升级比较大,特别是在源代码编译方面,苹果下足了功夫,编译时间不到原来的一半,忽然强烈觉得android在这方面需要加强啊: 其他不多说,X ...

  7. cat主要有三大功能

    cat主要有三大功能:1.一次显示整个文件.$ cat filename2.从键盘创建一个文件.$ cat > filename     只能创建新文件,不能编辑已有文件.3.将几个文件合并为一 ...

  8. 【HDOJ】3505 Writing Robot

    挺好的一道题目,我的做法是kmp+Dinic网络流.kmp求子串在P中出现的次数,从而计算love值.网络流主要用来处理最优解.case2中p1的love值是8,p2的love值是7,最终T包含p1和 ...

  9. 六月计划#2B(6.10-6.16)

    4/7 STL set 数学 快速傅立叶(FFT) 高斯消元 动态规划 斜率优化

  10. Windows系统中IIS 6.0+Tomcat服务器环境的整合配置过程

    IIS6.0+Tomcat整合 1.首先准备工作 Windows IIS 6.0 apache-tomcat-7.0.26.exe tomcat-connectors-1.2.33-windows-i ...