题面

好难表述啊~

在n*m的矩阵上,有一些大兵(为0),一些空地(一个正整数),障碍物(-1),现在摧毁一些空地,使所有大兵不能走出矩阵去(代价为表示空地的整数),求最小代价

思路:

网络流最小割

“阻止”,“最小”,看到这样的字眼,肯定就要想到最小割啊

在互相能到达的点之间建边,容量为INF,因为——它不能炸……

然后把每个点拆成入点出点,每个兵所在的出点和源点S直接相连,在最外面的点的出点和汇点T直接相连

最后套模板,OK了

最重要的还是建边,能够理解题目的意思,想出对应的策略

Code:

#include<bits/stdc++.h>
#define INF 0x7f7f7f7f
#define M 5010
#define N 2010
#define Mn 31
using namespace std;
int Cx[4]={1,0,0,-1};//预处理移动的方向
int Cy[4]={0,1,-1,0};
struct node{
int to,cap;
int nxt;
node(int a,int b):to(a),cap(b){ }
node(){ }
}b[M<<1];
int head[N],deep[N],a[Mn][Mn];
int n,m,S,T,Maxflow,Max,t=1;
bool p[Mn][Mn];
int read()
{
int s=0,p=1;
char c=getchar();
while(!isdigit(c))
{
if(c=='-')
p=-1;
c=getchar();
}
while(isdigit(c))
{
s=(s<<1)+(s<<3)+c-'0';
c=getchar();
}
return s*p;
}
int Cag(int x,int y)
{
return (x-1)*m+y;
}
void add(int x,int y,int cap)
{
b[++t]=node(y,cap);
b[t].nxt=head[x];
head[x]=t;
b[++t]=node(x,0);
b[t].nxt=head[y];
head[y]=t;
return;
}
void Add(int x,int y)
{
int Tx,Ty;
for(int i=0;i<4;i++)
{
Tx=x+Cx[i];Ty=y+Cy[i];
if(p[Tx][Ty])//边框的用处
add(Cag(x,y)+Max,T,INF);//在矩阵外就和汇点T相连
else
add(Cag(x,y)+Max,Cag(Tx,Ty),INF);//否则出点和入点相连
}
return;
}
bool BFS()
{
int i,cur;
int to,cap;
queue<int>p;
memset(deep,0,sizeof(deep));
p.push(S);deep[S]=1;
while(!p.empty())
{
cur=p.front();p.pop();
for(i=head[cur];i;i=b[i].nxt)
{
to=b[i].to;cap=b[i].cap;
if(cap&&!deep[to])
{
deep[to]=deep[cur]+1;
p.push(to);
if(to==T)
return 1;
}
}
}
return 0;
}
int Dinic(int k,int flow)
{
if(k==T)
return flow;
int i,to,cap,res,rest=flow;
for(i=head[k];i&&rest;i=b[i].nxt)
{
to=b[i].to;cap=b[i].cap;
if(cap&&deep[to]==deep[k]+1)
{
res=Dinic(to,min(rest,cap));
if(!res)
deep[to]=0;
b[i].cap-=res;
b[i^1].cap+=res;
rest-=res;
}
}
return flow-rest;
}
int main()
{
int i,j,flow;
n=read();m=read();
Max=n*m;T=Max+Max+1;//汇点T
for(i=1;i<=n;i++)//裱个框,方便判断
p[i][0]=p[i][m+1]=1;
for(i=1;i<=m;i++)
p[0][i]=p[n+1][i]=1;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
a[i][j]=read();
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
if(a[i][j]==-1)//如果是障碍就不建边
continue;
if(a[i][j]==0)//如果是大兵就与源点建边,注意,是出点!否则都要为zero了……
add(S,Cag(i,j)+Max,INF);
else//如果是空地,那么在自己的入点和出点之间建边
add(Cag(i,j),Cag(i,j)+Max,a[i][j]);//注意,这里的容量是a[i][j],就是要炸多少次
Add(i,j);//放个函数里看看能不能和四周相连
}
while(BFS())//Dinic模板
while((flow=Dinic(S,INF)))
Maxflow+=flow;
printf("%d",Maxflow);
return 0;
}

推荐题目

Luogu P2472 [SCOI2007]蜥蜴

有点类似,但很不相同!

「Luogu P3866」[TJOI2009]战争游戏 解题报告的更多相关文章

  1. 「Luogu P2015」二叉苹果树 解题报告

    题面 一个二叉树,边数为n\((2<n\le 100)\),每条边有一个权值,求剪枝后剩下p\((1<p<n)\)条边,使p条边的权值和最大 还看不懂?-- 2 5 input:5 ...

  2. 「Luogu P1210」回文检测 解题报告

    题面 这是一道诡异的黄题 居然让你求一串吧啦吧啦的东西中 字母(大小写)最长的回文串的长度,还要输出完整的串 吐血 思路: 保持淡定,我们啥都不会,就会Manacher,那就用Manacher大法! ...

  3. 「Luogu P4987」回文项链 解题报告

    题面 求环中的长度为k(k为奇数)且回文中心不同的回文串个数 思路: 刚学manacher算法,就送上一道模板题,此题注重对manacher算法的理解 Manacher,但是不用插入其他符号,因为k是 ...

  4. 「Luogu P1435」回文字串 解题报告

    题面 主要大衣大意: 给定一个字符串,求至少加入多少个字符才能使字符串变成回文字符串 下面就是我一本正经的胡说八道题解 思路: 很显然,这应该是一道典型的最长公共子序列的题目 因此,主要思想就是DP ...

  5. 「CTS2019 | CTSC2019」氪金手游 解题报告

    「CTS2019 | CTSC2019」氪金手游 降 智 好 题 ... 考场上签到失败了,没想容斥就只打了20分暴力... 考虑一个事情,你抽中一个度为0的点,相当于把这个点删掉了(当然你也只能抽中 ...

  6. 「CodeForces 546B」Soldier and Badges 解题报告

    CF546B Soldier and Badges 题意翻译 给 n 个数,每次操作可以将一个数 +1,要使这 n 个数都不相同, 求最少要加多少? \(1 \le n \le 3000\) 感谢@凉 ...

  7. P3866 [TJOI2009]战争游戏

    P3866 [TJOI2009]战争游戏 题目背景 小R正在玩一个战争游戏.游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中.每支敌军都 ...

  8. P3866 [TJOI2009]战争游戏 最小割

    $ \color{#0066ff}{ 题目描述 }$ 小R正在玩一个战争游戏.游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中.每支敌军 ...

  9. [TJOI2009] 战争游戏

    题目背景 小R正在玩一个战争游戏.游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中.每支敌军都可以从当前所在的格子移动到四个相邻的格子之 ...

随机推荐

  1. CentOs7 使用iptables开启关闭端口

    介绍 iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分 iptables文件设置路径:命令:vim /etc/sysconfig/iptables-config 注 ...

  2. @hdu - 6427@ Problem B. Beads

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有 m 种不同颜色的珠子,颜色分别为 1~m,每一种颜色的珠子有 ...

  3. 2016 年度开源中国新增开源软件排行榜 TOP 100

    2016 年度开源中国新增开源软件排行榜 TOP 100 2016 年度开源中国新增开源软件排行榜 TOP 100 新鲜出炉!本榜单根据 2016 年开源中国新收录的 3030 款软件的关注度和活跃度 ...

  4. 神经网络入门——6and感知机

    AND 感知器练习       AND 感知器的权重和偏置项是什么? 把权重(weight1, weight2)和偏置项 bias 设置成正确的值,使得 AND 可以实现上图中的运算.   在这个例子 ...

  5. H3C 面向连接和无连接的服务

  6. Python--day71--内容回顾

  7. CSS 伸缩布局

    转载于:https://blog.csdn.net/weixin_41342585/article/details/80140513 1. flex-direction:设置伸缩容器中成员的排列方式 ...

  8. java 基本数据类型的自动拆箱与装箱

    ——>  -128~127之间的特殊性.为什么要这样设计,好处? ——>  享元模式(Flyweight Pattern):享元模式的特点是,复用我们内存中已存在的对象,降低系统创建对象实 ...

  9. linux 位操作

    atomic_t 类型在进行整数算术时是不错的. 但是, 它无法工作的好, 当你需要以原子方 式操作单个位时. 为此, 内核提供了一套函数来原子地修改或测试单个位. 因为整个操作 在单步内发生, 没有 ...

  10. 2019-3-8-为何使用-DirectComposition

    title author date CreateTime categories 为何使用 DirectComposition lindexi 2019-3-8 8:56:9 +0800 2018-04 ...