题目链接:http://codeforces.com/gym/101149/problem/D

题目大意:

堡垒受到攻击。堡垒是n*m的矩阵,矩阵里刚开始都是平地,然后那个数值表示在当前平地上建一面墙需要a[i][j]的时间。目前我们在位置(r, c),我们找一种方法,把(r,c)全部围起来需要的最短时间?

思路:拆点,拆成in和out两个,in和out之间的cap就是a[i][j],然后就是简单的建边拉。

  1. //看看会不会爆int!数组会不会少了一维!
  2. //取物问题一定要小心先手胜利的条件
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. #pragma comment(linker,"/STACK:102400000,102400000")
  6. #define LL long long
  7. #define ALL(a) a.begin(), a.end()
  8. #define pb push_back
  9. #define mk make_pair
  10. #define fi first
  11. #define se second
  12. #define haha printf("haha\n")
  13.  
  14. const int maxn = * * + ;
  15. const int INF = 0x3f3f3f3f;
  16. struct Edge {
  17. int from, to, cap, flow;
  18. };
  19.  
  20. struct Dinic {
  21. int n, m, s, t; ///节点的个数,边的编号,起点,终点
  22. vector<Edge> edges; // 边数的两倍
  23. vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
  24. bool vis[maxn]; // BFS使用
  25. int d[maxn]; // 从起点到i的距离
  26. int cur[maxn]; // 当前弧指针
  27. /////////蓝书363
  28. int inq[maxn]; // 是否在队列中
  29. int p[maxn]; // 上一条弧
  30. int a[maxn]; //可改进量
  31.  
  32. void ClearAll(int n) {
  33. this->n = n; ///这个赋值千万不能忘
  34. for(int i = ; i < n; i++) G[i].clear();
  35. edges.clear();
  36. }
  37.  
  38. void ClearFlow() { ///清除流量,例如蓝书368的UVA11248里面的优化,就有通过清除流量来减少增广次数的
  39. for(int i = ; i < edges.size(); i++) edges[i].flow = ;
  40. }
  41.  
  42. void Reduce() {///直接减少cap,也是减少增广次数的
  43. for(int i = ; i < edges.size(); i++) edges[i].cap -= edges[i].flow;
  44. }
  45.  
  46. void AddEdge(int from, int to, int cap) {
  47. edges.push_back((Edge){from, to, cap, });
  48. edges.push_back((Edge){to, from, , });
  49. m = edges.size();
  50. G[from].push_back(m-);
  51. G[to].push_back(m-);
  52. }
  53.  
  54. bool BFS() {///bfs构建层次图
  55. memset(vis, , sizeof(vis));
  56. queue<int> Q;
  57. Q.push(s);
  58. vis[s] = ;
  59. d[s] = ;
  60. while(!Q.empty()) {
  61. int x = Q.front(); Q.pop();
  62. for(int i = ; i < G[x].size(); i++) {
  63. Edge& e = edges[G[x][i]];
  64. if(!vis[e.to] && e.cap > e.flow) {//只考虑残量网络中的弧
  65. vis[e.to] = ;
  66. d[e.to] = d[x] + ;
  67. Q.push(e.to);
  68. }
  69. }
  70. }
  71. return vis[t];
  72. }
  73.  
  74. int DFS(int x, int a) {///a表示目前为止,所有弧的最小残量。但是也可以用它来限制最大流量,例如蓝书368LA2957,利用a来保证增量,使得最后maxflow=k
  75. if(x == t || a == ) return a;
  76. int flow = , f;
  77. for(int& i = cur[x]; i < G[x].size(); i++) {//从上次考虑的弧,即已经访问过的就不需要在访问了
  78. Edge& e = edges[G[x][i]];
  79. if(d[x] + == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > ) {
  80. e.flow += f;
  81. edges[G[x][i]^].flow -= f;
  82. flow += f;
  83. a -= f;
  84. if(a == ) break;//如果不在这里终止,效率会大打折扣
  85. }
  86. }
  87. return flow;
  88. }
  89. /**最大流*/
  90. int Maxflow(int s, int t) {
  91. this->s = s; this->t = t;
  92. int flow = ;
  93. while(BFS()) {
  94. memset(cur, , sizeof(cur));
  95. flow += DFS(s, INF);///这里的INF可以发生改变,因为INF保证的是最大残量。但是也可以通过控制残量来控制最大流
  96. }
  97. return flow;
  98. }
  99.  
  100. /**最小割*/
  101. char ch[maxn][maxn];
  102. void Mincut(int x, int y) { /// call this after maxflow求最小割,就是S和T中还存在流量的东西
  103. BFS();///重新bfs一次
  104. for (int i = ; i < x; i++)
  105. for (int j = ; j < y; j++)
  106. ch[i][j] = '.';
  107. int cnt = ;
  108. for(int i = ; i < edges.size(); i++) {
  109. Edge& e = edges[i];
  110. if(vis[e.from] && !vis[e.to] && e.cap >= && e.to - e.from == x * y) {///这里和ISAP不一样
  111. cnt++;
  112. int nx = e.from / y, ny = e.from - nx * y;
  113. ch[nx][ny] = 'X';
  114. //printf("e.from = %d e.to = %d nx = %d ny = %d\n", e.from, e.to, nx, ny);
  115. }
  116. }
  117. //printf("cnt = %d\n", cnt);
  118. for (int i = ; i < x; i++){
  119. for (int j = ; j < y; j++){
  120. printf("%c", ch[i][j]);
  121. }
  122. cout << endl;
  123. }
  124.  
  125. }
  126.  
  127. void debug(){///debug
  128. for (int i = ; i < edges.size(); i++){
  129. printf("u = %d v = %d cap = %d flow = %d\n", edges[i].from + , edges[i].to + , edges[i].cap, edges[i].flow);
  130. }
  131. }
  132. };
  133. Dinic g;
  134.  
  135. int n, m, a, b;
  136. int atlas[maxn][maxn];
  137.  
  138. int dx[] = {, -, , };
  139. int dy[] = {, , , -};
  140. int in_id(int x, int y){
  141. return x * m + y;
  142. }
  143. int out_id(int x, int y){
  144. return n * m + x * m + y;
  145. }
  146.  
  147. int main(){
  148. scanf("%d%d%d%d", &n, &m, &a, &b);
  149. a--, b--;
  150. for (int i = ; i < n; i++){
  151. for (int j = ; j < m; j++){
  152. scanf("%d", &atlas[i][j]);
  153. }
  154. }
  155. int s = in_id(a, b), t = n * m * + ;
  156. g.ClearAll(t);
  157. for (int i = ; i < n; i++){
  158. for (int j = ; j < m; j++){
  159. if (a == i && b == j) {
  160. for (int k = ; k < ; k++){
  161. int nx = i + dx[k], ny = j + dy[k];
  162. if (nx < || ny < || nx >= n || ny >= m) continue;
  163. g.AddEdge(in_id(i, j), in_id(nx, ny), INF);
  164. }
  165. continue;
  166. }
  167. else {
  168. g.AddEdge(in_id(i, j), out_id(i, j), atlas[i][j]);
  169. if (i == || j == || i == n- || j == m-)
  170. g.AddEdge(out_id(i, j), t, INF);
  171. }
  172. for (int k = ; k < ; k++){
  173. int nx = i + dx[k], ny = j + dy[k];
  174. if (nx < || ny < || nx >= n || ny >= m) continue;
  175. if (nx == a && ny == b) continue;
  176. g.AddEdge(out_id(i, j), in_id(nx, ny), INF);
  177. }
  178. }
  179. }
  180. printf("%d\n", g.Maxflow(s, t));
  181. g.Mincut(n, m);
  182. return ;
  183. }

最小割 D. Behind the Wall Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest的更多相关文章

  1. 几何+思维 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest K. Revenge of the Dragon

    题目链接:http://codeforces.com/gym/101149/problem/K 题目大意: 给你两个点a,b.一个人在a点,一个人在b点,b点的人要追杀a的点,他的跑步速度是a的两倍. ...

  2. 最短路+找规律 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest L. Right Build

    题目链接:http://codeforces.com/gym/101149/problem/L 题目大意:有n个点(其实是n+1个点,因为编号是0~n),m条有向边.起点是0,到a和b两个节点,所经过 ...

  3. 贪心+离散化+线段树上二分。。。 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest G. Of Zorcs and Axes

    题目链接:http://codeforces.com/gym/101149/problem/G 题目大意:给你n对数字,为(a[i], b[i]),给你m对数字,为(w[i], c[i]).给n对数字 ...

  4. 训练报告 (2014-2015) 2014, Samara SAU ACM ICPC Quarterfinal Qualification Contest

    Solved A Gym 100488A Yet Another Goat in the Garden   B Gym 100488B Impossible to Guess Solved C Gym ...

  5. 【最小割】【Dinic】HihoCoder - 1252 - The 2015 ACM-ICPC Asia Beijing Regional Contest - D - Kejin Game

    题意:有一个技能学习表,是一个DAG,要想正常学习到技能x,要将指向x的技能全部先学到,然后会有一个正常花费cx.然后你还有一种方案,通过氪金dx直接获得技能x.你还可以通过一定的代价,切断一条边.问 ...

  6. Samara SAU ACM ICPC 2013-2014 Quarterfinal Qualification Contest

    A: 简单题,因为题目中说了不会有数据相同: #include<cstdio> #include<algorithm> #define maxn 200005 using na ...

  7. sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)

    The Android University ACM Team Selection Contest Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里 ...

  8. Golden Eggs HDU - 3820(最小割)

    Golden Eggs Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. BZOJ 1391: [Ceoi2008]order [最小割]

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Statu ...

随机推荐

  1. POJ 1239 Increasing Sequences 动态规划

    题目链接: http://poj.org/problem?id=1239 Increasing Sequences Time Limit: 1000MSMemory Limit: 10000K 问题描 ...

  2. 实现二叉树(search)

    ★实验任务 可怜的 Bibi 刚刚回到家,就发现自己的手机丢了,现在他决定回头去搜索 自己的手机. 现在我们假设 Bibi 的家位于一棵二叉树的根部.在 Bibi 的心中,每个节点 都有一个权值 x, ...

  3. Gradle入门(1):安装

    在Ubuntu下,执行以下命令: sudo apt-get install gradle 安装完成后,执行命令: gradle -v 得到以下信息: Picked up _JAVA_OPTIONS:  ...

  4. PAT 甲级 1141 PAT Ranking of Institutions

    https://pintia.cn/problem-sets/994805342720868352/problems/994805344222429184 After each PAT, the PA ...

  5. js ajax 经典案例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. [转帖]nvidia nvlink互联与nvswitch介绍

    nvidia nvlink互联与nvswitch介绍 https://www.chiphell.com/thread-1851449-1-1.html 差不多在一个月前在年度gtc会议上,老黄公开了d ...

  7. java super

    用法: 1.子类构造器里面默认调用父类构造器 2.调用父类的属性,方法

  8. BZOJ3444 最后的晚餐(并查集)

    容易发现只要图中有非链部分则无解.剩下就非常简单了. #include<iostream> #include<cstdio> #include<cmath> #in ...

  9. iPhone X 的原深感模组

    物理与数字世界正走向融合,我们每天醒来的时间.睡眠时长.心率和步数等数据都会被分享.上传并转化为分析数据.无处不自的 AI.互联互通和软件平台将改变用户对现实的感知. 2018 年的 CES 展(国际 ...

  10. easyui动态生成双列头

    实习时老大交给任务,让我做这样一个效果,选择日期并点击查询时,动态生成列头,下一列要求对应日期的星期. 效果图: 下面贴出查询的单击函数: //查询按钮 function queryByDate(){ ...