[9018_2101]保卫萝卜

题目描述

一群怪物正向着你的萝卜出发……

这群怪物共有N只,第i只怪物的HP为Ai,当怪物的HP减少到0时,这个怪物就被摧毁了。现在你有M座防御塔,其中第i个防御塔每秒可以减少一只怪物Bi点的HP。由于怪物有不同的属性,所以某些怪物会对某些防御塔免疫。

你的任务是计算至少需要多少时间才能消灭所有的怪物。

 

输入

第一行两个正整数N,M

第二行N个正整数,表示A1~An

第三行M个正整数,表示B1~Bn

接下来是一个M*N的矩阵,矩阵中每个元素均为0或1。第i行第j列为1表示第i座防御塔可以攻击第j只怪物,为0表示第j只怪物对第i座防御塔的攻击免疫。

 

输出

一行,一个实数,表示所需的最小时间。保留3位小数

 

样例输入

2 2
3 10
4 6
0 1
1 1

样例输出

1.300

提示

 

前0.5s "Times New Roman"">,防御塔1攻击2号怪物,防御塔2 "Times New Roman"">攻击1号怪物。1号怪物被摧毁,2 "Times New Roman"">号怪物剩下8点HP。


接下来0.8s "Times New Roman"">,1号和2号防御塔同时攻击2 "Times New Roman"">号怪物。2号怪物被摧毁。


对于全部的数据,1<=N,M<=50 "Times New Roman"">,1<=Ai<=10^5 "Times New Roman"">,1<=Bi<=10^4 "Times New Roman"">,输入数据确保不存在同时对所有防御塔免疫的怪物

二分答案+最大流check
二分击杀所有怪物所用时间
从源点s向每座塔连一条容量为t*b[i]的边,表示塔在t秒内的总输出
从每座塔向不能免疫它的攻击的怪物连一条容量为INF的边,表示该塔可以攻击怪物
从每个怪物向汇点连一条容量为怪物血量的边,表示该怪物能承受这么多的输出
对于每个二分出来的t,检查是否满流
若满流,表示怪物全部被击杀,可以减少时间,否则,表示有怪物还活着,需增加时间
注意浮点误差
#include<iostream> 
#include<cstdio> 
#include<cstring> 
#include<cmath> 
#define eps 1e-5 
#define INF 999999999 
using namespace std; 
int h[1000],to[100000],nxt[100000],k=1,level[1000],iter[1000],s,t,n,m;double tot=0.0; 
int H=0,T=0,que[100000],A[51],B[51];double ca[100000]; 
bool mp[1000][1000]; 
void ins(int u,int v,double cap) 
{ 
    nxt[++k]=h[u];to[k]=v;ca[k]=cap;h[u]=k; 
    nxt[++k]=h[v];to[k]=u;ca[k]=0;h[v]=k; 
} 
void bfs() 
{ 
    memset(level,0,sizeof(level)); 
    H=T=0;que[T++]=s;level[s]=1; 
    while(H!=T) 
    { 
        int u=que[H++]; 
        for(int i=h[u];i;i=nxt[i]) 
        { 
            if(!level[to[i]]&&abs(ca[i])>=eps) 
            { 
                level[to[i]]=level[u]+1;que[T++]=to[i]; 
            } 
        } 
    } 
} 
double dfs(int u,double f) 
{ 
    if(u==t)return f; 
    double used=0,w; 
    for(int &i=iter[u];i;i=nxt[i]) 
    { 
        if(abs(ca[i])>=eps&&level[to[i]]==level[u]+1) 
        { 
            w=f-used;w=dfs(to[i],min(w,ca[i])); 
            if(abs(w)>=eps) 
            { 
                ca[i]-=w;ca[i^1]+=w;used+=w;if(used==f)return f; 
            } 
        } 
    } 
    return used; 
} 
double dinic() 
{ 
    double flow=0; 
    for(;;) 
    { 
        for(int i=1;i<=n+m+2;i++)iter[i]=h[i]; 
        bfs();if(!level[t])return flow; 
        flow+=dfs(s,INF); 
    } 
    return flow; 
} 
double erfen(double L,double R) 
{ 
    while(R-L>eps) 
    { 
        double mid=(L+R)/2; 
        k=1;memset(h,0,sizeof(h)); 
        for(int i=1;i<=n;i++)ins(i+m,t,(double)A[i]); 
        for(int i=1;i<=m;i++)ins(s,i,(double)mid*B[i]); 
        for(int i=1;i<=m;i++) 
        for(int j=1;j<=n;j++)ins(i,j+m,(double)INF); 
        double ff=dinic(); 
        if(abs(ff-tot)<eps)R=mid; 
        else L=mid; 
    } 
    return L; 
} 
int main() 
{ 
    scanf("%d%d",&n,&m);s=n+m+1,t=n+m+2; 
    for(int i=1;i<=n;i++){scanf("%d",&A[i]);tot+=(double)A[i];} 
    for(int i=1;i<=m;i++)scanf("%d",&B[i]); 
    for(int i=1;i<=m;i++) 
    for(int j=1;j<=n;j++) 
    { 
        int q;scanf("%d",&q);mp[i][j]=1; 
    } 
    printf("%.3lf",erfen(0.0,5000000.0)); 
    return 0; 
} 

 

 

posted @ 2017-07-06 19:41  lher  阅读(374)  评论(0编辑  收藏  举报