传送门:https://www.luogu.org/problemnew/show/P3324

首先瞅一眼数据范围,发现m, n都很小,所以就可以初步断定这是一道网络流的题。

因为题中说每一个武器只能攻击特定的机器人,所以可以想象成这把武器有一条指向该机器人的边,那流量是多少呢?这是不确定的,因为武器攻击机器人的策略是不知道的。不过有一点可以确定,就是在时间t内,这把武器造成的伤害一定是b[i] * t,如果把武器i和源点连一条边,那么这条边的容量就是b[i] * t。

在考虑每一个机器人的装甲值,如果给个机器人i和汇点建立一条边,那么容量就是a[i]。这样我们就成功建立了一个图。

然后对 t 进行二分,如果在当时间为 t 时,到汇点的流量是sum(a[i]),那么就说明所有机器人都被打败了,就在左区间二分,否则说明 t 取小了,就在右区间二分。

因为题中说输出结果与标准答案的绝对误差不超过10-3即视为正确,所以我们把防御值扩大10000倍,这样在long long 范围内就可以解决了。

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<cstdlib>
  7. #include<cctype>
  8. #include<stack>
  9. #include<queue>
  10. #include<vector>
  11. using namespace std;
  12. #define enter printf("\n")
  13. #define space printf(" ")
  14. #define Mem(a) memset(a, 0, sizeof(a));
  15. typedef long long ll;
  16. typedef double db;
  17. const int INF = 0x3f3f3f3f;
  18. const db eps = 1e-;
  19. const int maxn = 2e5 + ;
  20. inline ll read()
  21. {
  22. ll ans = ;
  23. char ch = getchar(), last = ' ';
  24. while(!isdigit(ch)) {last = ch; ch = getchar();}
  25. while(isdigit(ch))
  26. {
  27. ans = ans * + ch - ''; ch = getchar();
  28. }
  29. if(last == '-') ans = -ans;
  30. return ans;
  31. }
  32. inline void write(ll x)
  33. {
  34. if(x < ) putchar('-'), x = -x;
  35. if(x >= ) write(x / );
  36. putchar(x % + '');
  37. }
  38. //mrclr//
  39.  
  40. int n, m, t;
  41. ll a[], b[];
  42. bool s[][];
  43. struct Edge
  44. {
  45. int from, to;
  46. ll cap, flow;
  47. };
  48. vector<Edge> edges;
  49. vector<int> G[maxn];
  50.  
  51. void init()
  52. {
  53. edges.clear();
  54. for(int i = ; i < maxn; ++i) G[i].clear();
  55.  
  56. }
  57. void addEdge(int from, int to, ll w) //以下就是网络流的板子了
  58. {
  59. edges.push_back((Edge){from, to, w, });
  60. edges.push_back((Edge){to, from, , });
  61. int sz = edges.size();
  62. G[from].push_back(sz - );
  63. G[to].push_back(sz - );
  64. }
  65.  
  66. int dis[maxn];
  67. bool vis[maxn];
  68. bool bfs()
  69. {
  70. Mem(vis);
  71. queue<int> q;
  72. q.push(); vis[] = ;
  73. dis[] = ;
  74. while(!q.empty())
  75. {
  76. int now = q.front(); q.pop();
  77. for(int i = ; i < (int)G[now].size(); ++i)
  78. {
  79. Edge& e = edges[G[now][i]];
  80. if(!vis[e.to] && e.cap > e.flow)
  81. {
  82. vis[e.to] = ;
  83. dis[e.to] = dis[now] + ;
  84. q.push(e.to);
  85. }
  86. }
  87. }
  88. return vis[t];
  89. }
  90. int cur[maxn];
  91. ll dfs(int now, ll a)
  92. {
  93. if(now == t || !a) return a;
  94. ll flow = , f;
  95. for(int& i = cur[now]; i < (int)G[now].size(); ++i)
  96. {
  97. Edge& e = edges[G[now][i]];
  98. if(dis[e.to] == dis[now] + && (f = dfs(e.to, min(a, e.cap - e.flow))) > )
  99. {
  100. e.flow += f;
  101. edges[G[now][i] ^ ].flow -= f;
  102. flow += f; a -= f;
  103. if(!a) break;
  104. }
  105. }
  106. return flow;
  107. }
  108.  
  109. ll maxflow()
  110. {
  111. ll flow = ;
  112. while(bfs())
  113. {
  114. Mem(cur);
  115. flow += dfs(, (ll)INF * INF);
  116. }
  117. return flow;
  118. }
  119.  
  120. ll sum = ;
  121.  
  122. bool judge(ll tp)
  123. {
  124. init();
  125. for(int i = ; i <= m; ++i) addEdge(, i, b[i] * tp); //把武器和源点建立一条容量为b[i] * time 的边
  126. for(int i = ; i <= n; ++i) addEdge(i + m, t, a[i]); //把机器人和汇点建立一条容量为a[i]的边
  127. for(int i = ; i <= m; ++i)
  128. for(int j = ; j <= n; ++j)
  129. if(s[i][j]) addEdge(i, j + m, INF);
  130. //如果武器i能攻击机器人j,就建边,容量无穷,因为武器i有b[i] * time的限制
  131. // printf("%lld %lld\n", maxflow(), sum);
  132. //调试的时候请不要这么写,因为maxflow()跑完后已经成残量网络了,在上面跑自然不对
  133. return maxflow() == sum;
  134. }
  135.  
  136. int main()
  137. {
  138. n = read(); m = read(); //防御值扩大1e4倍
  139. t = n + m + ;
  140. for(int i = ; i <= n; ++i) {a[i] = read(); a[i] *= ; sum += a[i];}
  141. for(int i = ; i <= m; ++i) b[i] = read();
  142. for(int i = ; i <= m; ++i)
  143. for(int j = ; j <= n; ++j)
  144. {int x = read(); s[i][j] = x;}
  145. ll L = , R = (ll)INF * (ll)INF;
  146. while(L < R)
  147. {
  148. int mid = (L + R) >> ;
  149. if(judge(mid)) R = mid;
  150. else L = mid + ;
  151. }
  152. printf("%.5lf\n", (double)L / );
  153. return ;
  154. }

P3324 [SDOI2015]星际战争的更多相关文章

  1. 洛谷P3324 [SDOI2015]星际战争

    题目:洛谷P3324 [SDOI2015]星际战争 思路: 类似<导弹防御塔>,因为题目保证有解,花费时间小于最终答案时一定无法消灭所有敌人,只要花费时间大于等于最终答案都可以消灭所有敌人 ...

  2. BZOJ 3993 Luogu P3324 [SDOI2015]星际战争 (最大流、二分答案)

    字符串终于告一段落了! 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3993 (luogu) https://www.l ...

  3. 洛谷P3324 [SDOI2015]星际战争 题解

    题目链接: https://www.luogu.org/problemnew/show/P3324 分析: 因为本题的时间点较多,不能枚举,但发现有单调性,于是二分答案,二分使用的时间TTT 每个攻击 ...

  4. 洛谷$P3324\ [SDOI2015]$星际战争 网络流+二分

    正解:网络流+二分 解题报告: 传送门$QwQ$ 其实我第一反应是费用流来着,,,但是仔细想了下发现我不会实现各个武器之间独立同时?而且攻击是连续的答案可能是小数嘛$QwQ$. 所以显然不是递推就二分 ...

  5. Luogu P3324 [SDOI2015]星际战争

    二分+最大流 首先考虑二分答案 然后可以发现对于已知时间,判断是否可以将所有机器人摧毁可以用网络流 建立源点和汇点,源点向每一个激光武器连一条容量为$time*b[i]$的边,表示该激光武器在$tim ...

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

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

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

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

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

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

  9. 3993: [SDOI2015]星际战争

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

随机推荐

  1. js 前端分页空间控件

    现在web注重用户体验与交互性,ajax 提交数据的方式很早就流行了,它能够在不刷新网页的情况下局部刷新数据.前端分页多是用ajax请求数据(其他方式也有比如手动构造表单模拟提交事件等).通过js将查 ...

  2. NPOI 之导入导出

    转自https://www.cnblogs.com/zuowj/archive/2015/05/04/4475663.html转别人的,做了一点点改动 using NPOI.HSSF.UserMode ...

  3. 第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; Select 列 into 新表;字符串函数;日期函数

    第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all;  ...

  4. LDA(线性判别分析,Python实现)

    源代码: #-*- coding: UTF-8 -*- from numpy import * import numpy def lda(c1,c2): #c1 第一类样本,每行是一个样本 #c2 第 ...

  5. [日常] Go语言圣经-并发的非阻塞缓存

    1.go test命令是一个按照约定和组织进行测试的程序2.竞争检查器 go run -race 附带一个运行期对共享变量访问工具的test,出现WARNING: DATA RACE 说明有数据竞争3 ...

  6. Calendar类的一些不易区分的属性

    1.Calendar.MONTH 月份从0-11,获取之后需要加1才能得到真正的月份 2.Calendar.DAY_OF_WEEK 本周的第几天,从星期天开始算 3.Calendar.WEEK_OF_ ...

  7. 获取本机的ip地址(排除虚拟机,蓝牙等ip)

    项目中遇到了要获取本地ip的需求,网上查找资料遇到很多坑,很多Java获取本机ip地址的方法要么是根本获取不到,要么是获取的有问题. 网上常见的方法如下 InetAddress.getLocalHos ...

  8. MVC--DefaultModelBinder解析request参数

    转载:http://www.cnblogs.com/leotsai/p/ASPNET-MVC-DefaultModelBinder.html 看到很多ASP.NET MVC项目还在从request.q ...

  9. win7游戏窗口设置

    在开始搜索框输入regedit打开注册表,定位到HKEY_LOCAL_MACHINE------SYSTEM------ControlSet001-------Control-------Graphi ...

  10. Angular4.+ ngx-bootstrap Pagination 自定义分页组件

    Angular4 随笔(二)  ——自定义分页组件 1.简介 本组件主要是实现了分页组件显示功能,通过使用 ngx-bootstrap Pagination分页组件实现. 基本逻辑: 1.创建一个分页 ...