题目描述

3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战。

在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai。当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器人就被摧毁了。

X军团有M个激光武器,其中第i个激光武器每秒可以削减一个巨型机器人Bi的装甲值。激光武器的攻击是连续的。

这种激光武器非常奇怪,一个激光武器只能攻击一些特定的敌人。Y军团看到自己的巨型机器人被X军团一个一个消灭,他们急需下达更多的指令。

为了这个目标,Y军团需要知道X军团最少需要用多长时间才能将Y军团的所有巨型机器人摧毁。但是他们不会计算这个问题,因此向你求助。

输入输出格式

输入格式:

第一行,两个整数,N、M。第二行,N个整数,A1、A2...AN。第三行,M个整数,B1、B2...BM。接下来的M行,每行N个整数,这些整数均为0或者1。这部分中的第i行的第j个整数为0表示第i个激光武器不可以攻击第j个巨型机器人,为1表示第i个激光武器可以攻击第j个巨型机器人。

输出格式:

一行,一个实数,表示X军团要摧毁Y军团的所有巨型机器人最少需要的时间。输出结果与标准答案的绝对误差不超过10-3即视为正确。

输入输出样例

输入样例#1:

2 2
3 10
4 6
0 1
1 1
输出样例#1:

1.300000

说明

【样例说明1】

战斗开始后的前0.5秒,激光武器1攻击2号巨型机器人,激光武器2攻击1号巨型机器人。1号巨型机器人被完全摧毁,2号巨型机器人还剩余8的装甲值;

接下来的0.8秒,激光武器1、2同时攻击2号巨型机器人。2号巨型机器人被完全摧毁。

对于全部的数据,1<=N, M<=50,1<=Ai<=105,1<=Bi<=1000,输入数据保证X军团一定能摧毁Y军团的所有巨型机器人

[spj]

思路:

  二分+最大流;

  轻松ac;

  二分时间,用最大流判断是否能达到装甲总值;

来,上代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> #define maxn 101
#define INF 9999999.99
#define EFlit 10000.0 using namespace std; struct EdgeType {
int v,e; double f;
};
struct EdgeType edge[maxn*maxn<<]; int if_z,n,m,head[maxn<<],s,t=(maxn<<)-;
int ai[maxn],bi[maxn],tota,totb,map[maxn][maxn];
int deep[maxn<<],cnt; double dai[maxn],dbi[maxn]; char Cget; inline void in(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
return ;
} bool bfs()
{
queue<int>que;
memset(deep,-,sizeof(deep));
que.push(s);deep[s]=;
while(!que.empty())
{
int pos=que.front();que.pop();
for(int i=head[pos];i;i=edge[i].e)
{
if(deep[edge[i].v]<&&edge[i].f>)
{
deep[edge[i].v]=deep[pos]+;
if(edge[i].v==t) return true;
que.push(edge[i].v);
}
}
}
return false;
} double flowing(int now,double flow)
{
if(now==t||flow==) return flow;
double oldflow=;
for(int i=head[now];i;i=edge[i].e)
{
if(deep[edge[i].v]==deep[now]+&&edge[i].f>)
{
double pos=flowing(edge[i].v,min(flow,edge[i].f));
if(pos>)
{
flow-=pos;
oldflow+=pos;
edge[i].f-=pos;
edge[i^].f+=pos;
if(flow==) return oldflow;
}
}
}
if(oldflow==) deep[now]=-;
return oldflow;
} inline void edge_add(int u,int v,double f)
{
edge[++cnt].v=v,edge[cnt].f=f,edge[cnt].e=head[u],head[u]=cnt;
edge[++cnt].v=u,edge[cnt].f=,edge[cnt].e=head[v],head[v]=cnt;
} bool check(double ans_)
{
cnt=;
memset(head,,sizeof(head));
for(int i=;i<=m;i++) edge_add(s,i,dbi[i]*ans_);
for(int i=;i<=n;i++) edge_add(i+m,t,dai[i]);
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++)
{
if(map[i][j]) edge_add(i,j+m,INF);
}
}
double pos=;
while(bfs()) pos+=flowing(s,INF);
if(pos>=(double)tota-0.001) return true;
else return false;
} int main()
{
in(n),in(m);
for(int i=;i<=n;i++)
{
in(ai[i]);
tota+=ai[i];
dai[i]=ai[i];
}
for(int i=;i<=m;i++)
{
in(bi[i]);
totb+=bi[i];
dbi[i]=bi[i];
}
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++) in(map[i][j]);
}
double l=(double)tota/(double)totb,r=EFlit,mid,ans;
// double l=0,r=EFlit,mid,ans;
while(l<r)
{
mid=(l+r)/2.0;
if(check(mid)) ans=mid,r=mid-0.0001;
else l=mid+0.0001;
}
printf("%lf\n",ans);
return ;
}

AC日记——[SDOI2015]星际战争 洛谷 P3324的更多相关文章

  1. AC日记——联合权值 洛谷 P1351

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  2. AC日记——I Hate It 洛谷 P1531

    题目背景 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 题目描述 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的 ...

  3. AC日记——神奇的幻方 洛谷 P2615(大模拟)

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  4. AC日记——[CQOI2009]DANCE跳舞 洛谷 P3153

    [CQOI2009]DANCE跳舞 思路: 二分+最大流: 代码: #include <cstdio> #include <cstring> #include <iost ...

  5. AC日记——松江1843路 洛谷七月月赛

    松江1843路 思路: 三分: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define ...

  6. AC日记——严酷的训练 洛谷 P2430

    严酷的训练 思路: 背包: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 5005 int n,m,bi[m ...

  7. AC日记——[SDOI2010]大陆争霸 洛谷 P3690

    [SDOI2010]大陆争霸 思路: dijkstra模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn ...

  8. AC日记——小魔女帕琪 洛谷 P3802

    小魔女帕琪 思路: 概率公式计算: 代码: #include <bits/stdc++.h> using namespace std; ],sig; int main() { ;i< ...

  9. AC日记——双栈排序 洛谷 P1155

    双栈排序 思路: 二分图染+模拟: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #define ...

随机推荐

  1. matplot绘图(五)

    b3D图形绘制 # 导包:from mpl_toolkits.mplot3d.axes3d import Axes3Dimport matplotlib.pyplot as plt%matplotli ...

  2. java版RSA工具类

    /** * RSA算法加密/解密工具类 */ public class RSAUtils { private static final Logger LOGGER = LoggerFactory.ge ...

  3. spring boot yaml 自定义配置 映射到 java POJO

    只需要一个注解就ok: @ConfigurationProperties("user.other") “user.other” 这个值匹配的是user下的other对象 yaml ...

  4. Qt概念和快捷键

    Qt概念和快捷键 Qt简介        1.Qt的由来和发展 Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI程 ...

  5. LeetCode之螺旋矩阵

    问题 螺旋矩阵 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ ...

  6. poj-3278 catch that cow(搜索题)

    题目描述: Farmer John has been informed of the location of a fugitive cow and wants to catch her immedia ...

  7. light oj 1104 Birthday Paradox (概率题)

    Sometimes some mathematical results are hard to believe. One of the common problems is the birthday ...

  8. 水题:UVa213- Message Decoding

    Message Decoding Some message encoding schemes require that an encoded message be sent in two parts. ...

  9. Linux下open函数、read函数、write函数记录

    open() #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> int open( cons ...

  10. CodeForces 500E New Year Domino

    题意: 从左到右排列着\(n\)个多米诺骨牌,它们分别站在\(x\)轴上的位置\(p_i\)上且高度为\(l_i\). 当第\(i\)个多米诺骨牌向右倒下时,如果\(p_i < p_j \leq ...