题目背景

小R正在玩一个战争游戏。游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中。每支敌军都可以从当前所在的格子移动到四个相邻的格子之一,但是不能移动到包含障碍物的格子。如果敌军移动出了地图的边界,那么战争就失败了。

题目描述

现在你的任务是,在敌军开始移动前,通过飞机轰炸使得某些原本是空地的格子变得不可通行,这样就有可能阻止敌军移出地图边界(出于某种特殊的考虑,你不能直接轰炸敌军所在的格子)。由于地形不同的原因,把每个空地格子轰炸成不可通行所需的xx数目可能是不同的,你需要计算出要阻止敌军所需的最少的xx数。

输入输出格式

输入格式:

输入文件的第一行包含两个数M和N,分别表示矩阵的长和宽。接下来M行,每行包含用空格隔开的N个数字,每个数字表示一个格子的情况:若数字为-1,表示这个格子是障碍物;若数字为0,表示这个格子里有一支敌军;若数字为一个正数x,表示这个格子是空地,且把它轰炸成不可通行所需的xx数为x。

输出格式:

输出一个数字,表示所需的最少xx数。数据保证有解存在。

输入输出样例

输入样例#1:

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

6

说明

对50%的数据,1 ≤ M,N ≤ 10

对100%的数据,1 ≤ M,N ≤ 30

矩阵里的每个数不超过100

最小割套路题,拆点限流量,把0看成源,相邻的点之间连边,边界的点向汇连边,最小割就是答案。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1805;
#define pb push_back
const int inf=1<<30;
vector<int> g[maxn];
struct lines{
int to,flow,cap;
}l[maxn*233];
int S,t=-1,T,d[maxn],cur[maxn];
bool v[maxn]; inline void add(int from,int to,int cap){
l[++t]=(lines){to,0,cap},g[from].pb(t);
l[++t]=(lines){from,0,0},g[to].pb(t);
} inline bool BFS(){
memset(v,0,sizeof(v));
queue<int> q; q.push(S);
v[S]=1,d[S]=0;
int x; lines e; while(!q.empty()){
x=q.front(),q.pop();
for(int i=g[x].size()-1;i>=0;i--){
e=l[g[x][i]];
if(e.flow<e.cap&&!v[e.to]) v[e.to]=1,d[e.to]=d[x]+1,q.push(e.to);
}
} return v[T];
} int dfs(int x,int A){
if(x==T||!A) return A;
int flow=0,f,sz=g[x].size();
for(int &i=cur[x];i<sz;i++){
lines &e=l[g[x][i]];
if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(A,e.cap-e.flow)))){
A-=f,flow+=f;
e.flow+=f,l[g[x][i]^1].flow-=f;
if(!A) break;
}
} return flow;
} inline int max_flow(){
int an=0;
while(BFS()){
memset(cur,0,sizeof(cur));
an+=dfs(S,inf);
}
return an;
} int n,m,id[233][233],cnt=0,a[233][233];
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; inline void build(){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) if(a[i][j]>0) id[i][j]=++cnt; S=0,T=cnt*2+1; for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) if(a[i][j]>=0){
if(a[i][j]>0){
add(id[i][j],id[i][j]+cnt,a[i][j]);
if(i==1||i==n||j==1||j==m) add(id[i][j]+cnt,T,inf);
} for(int o=0,x,y;o<4;o++){
x=i+dx[o],y=j+dy[o];
if(x&&x<=n&&y&&y<=m&&id[x][y]) add(a[i][j]?id[i][j]+cnt:S,id[x][y],inf);
}
}
} int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); build();
printf("%d\n",max_flow()); return 0;
}

  

最新文章

  1. JS中创建函数的三种方式及区别
  2. 使用 SQL的 for xml path来进行字符串拼接 (group by)
  3. 问题解决——VC 断点 无效 一个可能情况?
  4. 让IE10等支持classList2.0(转)
  5. cat &lt;&lt;EOF用法
  6. SQL Server 数据查询 整理
  7. Rank List
  8. debug &amp;&amp; release
  9. ARCGIS二维三维放大缩小
  10. maven上传自定义jar到本地仓库
  11. Animation 案例解释
  12. 监控系统Opserver
  13. BEGINNING SHAREPOINT&amp;#174; 2013 DEVELOPMENT 第8章节--配送SP2013Apps
  14. java 虚拟机学习--未完
  15. 在Linux系统使用VMware安装虚拟机
  16. sdn-准备-虚拟机迁移-vxlan
  17. [js]变量提升-关于条件
  18. zstu 4247-萌新的旅行
  19. dynamic web module讲解
  20. 创建maven项目前的准备工作

热门文章

  1. (原)Unreal 渲染模块引言Temp
  2. DataSource的设置
  3. css background-size与背景图片填满div
  4. jquery serialize() 方法
  5. jQuery对象转化为DOM对象
  6. sqlalchemy presto 时间比较
  7. 四、vue派发更新
  8. Redis、Mongodb、memcache区别在哪里?
  9. Ubuntu扩展系统盘容量,虚拟机下
  10. PHP error_reporting