题意

\(m\)个人\(n\)个物品,第\(i\)个物品生命值为\(A_i\),第\(i\)个人每秒可以减少一个物品\(B_i\)的生命值,给出一个\(m \times n\)的矩阵,如果\(i\)行\(j\)列为\(1\),则表示第\(i\)个人可以攻击第\(j\)个物品,否则不能攻击,问至少需要多少秒,能干掉所有物品。一个物品被干掉当且仅当生命值小于等于\(0\)。(\(n, m \le 50, 1 \le A_i \le 10^5, 1 \le B_i \le 10^3\) )

分析

我们可以二分时间,然后判定。首先我们能列出一些约束,然后发现可以用上下界可行流来做。

题解

二分时间\(t\),令\(C(i, j)\)表示第\(i\)个人减少了\(j\)物品的血量,容易列出:

\[\sum_{j} C(i, j) \le t \times B_i
\]

\[\sum_{i} C(i, j) \ge A_j
\]

然后裸上上下界可行流即可。

(即使有\(2500\)个点....

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long double lf;
  4. const lf eps=1e-5, oo=1e150;
  5. const int N=55, M=55, nN=3005, nM=nN*8;
  6. inline int dcmp(lf a) {
  7. return a>-eps?a>=eps:-1;
  8. }
  9. int ihead[nN], cnt, A[N], B[M], ed[M][N], n, m;
  10. struct E {
  11. int next, from, to;
  12. lf cap;
  13. }e[nM];
  14. void add(int x, int y, lf cap) {
  15. e[++cnt]=(E){ihead[x], x, y, cap}; ihead[x]=cnt;
  16. e[++cnt]=(E){ihead[y], y, x, 0 }; ihead[y]=cnt;
  17. }
  18. lf isap(int s, int t, int n) {
  19. static int gap[nN], cur[nN], d[nN], p[nN];
  20. memset(gap, 0, sizeof(int)*(n+1));
  21. memset(d, 0, sizeof(int)*(n+1));
  22. memcpy(cur, ihead, sizeof(int)*(n+1));
  23. gap[0]=n;
  24. lf ret=0, f;
  25. for(int i, x=s; d[s]<n; ) {
  26. for(i=cur[x]; i; i=e[i].next) if(dcmp(e[i].cap)>0 && d[x]==d[e[i].to]+1) break;
  27. if(i) {
  28. p[e[i].to]=cur[x]=i; x=e[i].to;
  29. if(x==t) {
  30. for(f=oo; x!=s; x=e[p[x]].from) f=min(f, e[p[x]].cap);
  31. for(x=t; x!=s; x=e[p[x]].from) e[p[x]].cap-=f, e[p[x]^1].cap+=f;
  32. ret+=f;
  33. }
  34. }
  35. else {
  36. if(!--gap[d[x]]) break;
  37. d[x]=n;
  38. cur[x]=ihead[x];
  39. for(i=cur[x]; i; i=e[i].next) if(dcmp(e[i].cap)>0 && d[x]>d[e[i].to]+1) d[x]=d[e[i].to]+1;
  40. ++gap[d[x]];
  41. if(x!=s) x=e[p[x]].from;
  42. }
  43. }
  44. return ret;
  45. }
  46. bool check(lf R) {
  47. int in=0, all=n*m+n+m+2+2, s=n*m+n+m+1, t=s+1, S=t+1, T=S+1;
  48. memset(ihead, 0, sizeof(int)*(all+1));
  49. cnt=1;
  50. for(int i=1; i<=m; ++i) {
  51. int idi=n*m+i;
  52. add(s, idi, R*B[i]);
  53. for(int j=1; j<=n; ++j) {
  54. int idj=n*m+m+j;
  55. int id=(i-1)*n+j;
  56. add(idi, id, oo);
  57. if(ed[i][j]) {
  58. add(id, idj, oo);
  59. }
  60. }
  61. }
  62. for(int i=1; i<=n; ++i) {
  63. int id=n*m+m+i;
  64. add(id, T, A[i]);
  65. in+=A[i];
  66. }
  67. add(S, t, in);
  68. add(t, s, oo);
  69. lf sum=isap(S, T, all);
  70. if(dcmp(sum-in)!=0) {
  71. return 0;
  72. }
  73. return 1;
  74. }
  75. int main() {
  76. scanf("%d%d", &n, &m);
  77. for(int i=1; i<=n; ++i) {
  78. scanf("%d", &A[i]);
  79. }
  80. for(int i=1; i<=m; ++i) {
  81. scanf("%d", &B[i]);
  82. }
  83. for(int i=1; i<=m; ++i) {
  84. for(int j=1; j<=n; ++j) {
  85. scanf("%d", &ed[i][j]);
  86. }
  87. }
  88. lf l=0, r=1e6;
  89. while(dcmp(r-l)>0) {
  90. lf mid=(l+r)/2;
  91. if(check(mid)) {
  92. r=mid;
  93. }
  94. else {
  95. l=mid;
  96. }
  97. }
  98. printf("%.9Lf\n", r);
  99. return 0;
  100. }

【BZOJ】3993: [SDOI2015]星际战争的更多相关文章

  1. BZOJ 3993: [SDOI2015]星际战争 [二分答案 二分图]

    3993: [SDOI2015]星际战争 题意:略 R1D2T1考了裸二分答案+二分图最大匹配... #include <iostream> #include <cstdio> ...

  2. BZOJ 3993 [SDOI2015]星际战争 | 网络流 二分答案

    链接 BZOJ 3993 题解 这道题挺棵的-- 二分答案t,然后源点向武器连t * b[i], 武器向能攻击的敌人连1, 敌人向汇点连a[i],如果最大流等于所有敌人的a[i]之和则可行. #inc ...

  3. bzoj 3993: [SDOI2015]星际战争

    #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #def ...

  4. 网络流(二分):BZOJ 3993: [SDOI2015]星际战争

    Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈 地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型 ...

  5. 3993: [SDOI2015]星际战争

    3993: [SDOI2015]星际战争 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1244  Solved: ...

  6. bzoj千题计划131:bzoj3993: [SDOI2015]星际战争

    http://www.lydsy.com/JudgeOnline/problem.php?id=3993 二分答案 源点向武器连 mid*攻击力的边 机器人向汇点连 防御力 的边 武器i能攻击机器人j ...

  7. bzoj3993: [SDOI2015]星际战争(网络流)

    3993: [SDOI2015]星际战争 题目:传送门 题解: 洛谷AC了,但是因为bzoj的spj有问题所以暂时没A 一道老题目了,二分时间然后网络流判断. 每次st-->武器连时间*攻击力 ...

  8. BZOJ_3993_[SDOI2015]星际战争_二分+网络流

    BZOJ_3993_[SDOI2015]星际战争_二分+网络流 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进 ...

  9. 【BZOJ3993】[SDOI2015]星际战争 二分+最大流

    [BZOJ3993][SDOI2015]星际战争 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地 ...

随机推荐

  1. 在.net中使用GAC

    转自:http://blog.log4d.com/2011/01/gac/ GAC GAC是什么?是用来干嘛的?GAC的全称叫做全局程序集缓存,通俗的理解就是存放各种.net平台下面需要使用的dll的 ...

  2. Beanutils基本用法

    Beanutils用了魔术般的反射技术,实现了很多夸张有用的功能,都是C/C++时代不敢想的.无论谁的项目,始终一天都会用得上它.我算是后知后觉了,第一回看到它的时候居然错过. 1.属性的动态gett ...

  3. jquery扫尾

    blur和change事件的先后 change事件, 是要在失去焦点之后, 才和初始状态的值相比较, 如果在得到焦点等情况下, 你是无法和最后状态相比较等. 在失去焦点后, 首先触发等是change事 ...

  4. SHLVL 和 BASH_SUBSHELL 两个变量的区别

    SHLVL 是记录多个 Bash 进程实例嵌套深度的累加器,而 BASH_SUBSHELL 是记录一个 Bash 进程实例中多个子 Shell(subshell)嵌套深度的累加器. 看不懂上面这句话不 ...

  5. [Network] 计算机网络基础知识总结

    计算机网络学习的核心内容就是网络协议的学习.网络协议是为计算机网络中进行数据交换而建立的规则.标准或者说是约定的集合.因为不同用户的数据终端可能采取的字符集是不同的,两者需要进行通信,必须要在一定的标 ...

  6. Navigation Bar options for Android (based on photosomething project)

    1, Tab控件即标签页,可以在一页中切换显示n页内容,要使用此效果,需要用到TabHost和Tabwidget类.(过时了?) Tab控件具有两种实现过程,一是在同一个Activity中切换显示不同 ...

  7. 微信公众平台自定义菜单新增扫一扫、发图片、发位置 LBS运作更便捷

    今天微信公众平台发布更新,自定义菜单新增扫一扫.发图片.发送位置等功能,这对于有意挖掘微信LBS服务的运营者来说更便捷了,订阅号不用返回微信界面就能扫图.发送图片.调用地理位置,用户体验更友好,自然也 ...

  8. PHP如何快速读取大文件

    在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file.file_get_contents之类的函数,简简单单的几行代码就能 很漂亮的完成我们所需要的功能.但当所操作的文件是一个比较大的 ...

  9. PHP 版去bom头

    原理: 找出文件前3个字符 如果它们对应的ASCII 值分别是  239,187,191 则判断为bom头,去掉前3个字符. 代码实现如下: $basedir = isset($_GET['dir'] ...

  10. 委托 与 Lambda

    一.委托调用方式 1. 最原始版本: delegate string PlusStringHandle(string x, string y); class Program { static void ...