题目背景

ZRQ在洞穴中准备采集矿物的时候遇险了!洞穴要塌了

题目来源:zhoutb2333

题目描述

整个洞穴是一个 \(N*N\) 的方格图,每个格子形如 \((X,Y),1 \le X,Y \le N\) 。其中 \(X\) 表示从上到下的行数,\(Y\) 表示从左到右的列数。 \((1,1)\) 在左上角,\((1,N)\) 在右上角, \((N,1)\) 在左下角, \((N,N)\) 在右下角。

满足 \(X+Y\) 为奇数格子的有一个不稳定度 \(V_{X,Y}\) , \(X+Y\) 为偶数的格子的不稳定度为 \(0\) 。

ZRQ现在手里恰巧有 \(M\) 个可以支撑洞穴的柱子,柱子的力量可以认为是无穷大。

只要支撑住了一个格子那么这个格子的不稳定度将降为 \(0\) 。

每个柱子是 \(L\) 型的,它除了要占据当前的格子外,还需要占据两个相邻的格子(这三个格子形成 \(L\) 型,可以选择任意方向放置,一共有 \(4\) 个方向)。

柱子占据相邻的格子不会降低其不稳定度(换句话说就是柱子只有在拐角处有力量)

有些格子的顶已经塌下来了,无法在其位置放置柱子了,这些格子也不能被占据了。这样已经塌了的格子有 \(K\) 个(他们的不稳定度都为 \(0\) ,即使 \(X+Y\) 为奇数,塌下来的格子的不稳定度也会为 \(0\) )。

ZRQ想问你,在放置一些柱子后 ,最小的不稳定度之和为多少(可以不将 \(M\) 个柱子都放完)。

输入输出格式

输入格式:

第一行三个整数 \(N,M,K\)

接下来 \(N\) 行每行 \(N\) 个整数,表示每个格子的不稳定度,保证 \(X+Y\) 为偶数的格子和已经塌下的格子的不稳定度为 \(0\)

接下来 \(K\) 行每行 \(2\) 个整数 \(X,Y\) ,表示已经塌下的格子的坐标。

输出格式:

一行一个整数,表示最小的不稳定度的和。

输入输出样例

输入样例#1:

3 3 1
0 1 0
2 0 1
0 1 0
1 3

输出样例#1:

3

输入样例#2:

3 3 4
0 2 0
0 0 4
0 3 0
1 3
2 1
2 2
3 1

输出样例#2:

9

说明

共 \(10\) 个测试点,每个点 \(10\) 分,计 \(100\) 分。

对于测试点 \(1\) ~ \(3\) ,有 \(1 \le N \le 6\)

对于测试点 \(4\) ~ \(7\) ,有 \(1 \le N \le 11\)

对于测试点 \(8\) ~ \(10\) ,有 \(1 \le N \le 50\)

对于所有测试点, \(0 \le M \le \frac{N^2}{3}, 0 \le K \le N^2, 0 \le V_{X,Y} \le 10^6\)

样例#1解释:

显然无法让任意两个不稳定的格子都被拐角覆盖,于是将 \((2,1)\) 用拐角覆盖住即可。这样剩余的不稳定度为 \(V_{1,2}+V_{2,3}+V_{3,2}=1+1+1=3\) 。

样例#2解释:

一个都放不下,这样剩余的不稳定度为 \(V_{1,2}+V_{2,3}+V_{3,2}=2+4+3=9\) 。

题解

考虑费用流。

为了方便描述,偶数格表示的是 为偶数的格子,奇数格表示的是为奇数的格子。

首先拐⻆处肯定放在有危险度的格子上。然后可以把这个 'L' 形石头看做是一条从奇数列的偶数格到奇数格再到偶数列的偶数格的一条路径。于是建四列点,把奇数列的偶数格放在第一列,每个奇数格拆成两个点分别放在第二列和第三列,偶数列的偶数格放在第四列。第一列到第二列是如果点是相邻的则连容量为 \(1\) 费用为 \(0\) 的边,第三列到第四列同理,第二列到第三列的相同点则连容量为 \(1\) 费用为负的危险度的边,然后源点向第一列,第四列向汇点连容量为 \(1\) 费用为 \(0\) 的边。

然后跑最小费用最大流,当此次增广的费用是正的了或者增广了次时就break,因为可能根本就放不下个石头,后面增广的费用是为了得到最大流而退流形成的,并不需要石头越多越好,我们只希望费用最小。

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100+10,MAXM=50000+10,inf=0x3f3f3f3f;
int n,m,k,e=1,beg[MAXN*MAXN*2],nex[MAXM<<1],to[MAXM<<1],cap[MAXM<<1],was[MAXM<<1],ans,G[MAXN][MAXN],T[MAXN][MAXN],prex[MAXN*MAXN*2],s,t,pres[MAXN*MAXN*2],M[4][MAXN][MAXN],tot,p[MAXN*MAXN*2],level[MAXN*MAXN*2];
std::queue<int> q;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y,int z,int w)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
cap[e]=z;
was[e]=w;
to[++e]=x;
nex[e]=beg[y];
beg[y]=e;
cap[e]=0;
was[e]=-w;
}
inline bool bfs()
{
memset(level,inf,sizeof(level));
level[s]=0;
p[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
p[x]=0;
for(register int i=beg[x];i;i=nex[i])
if(cap[i]&&level[to[i]]>level[x]+was[i])
{
level[to[i]]=level[x]+was[i];
if(!p[to[i]])p[to[i]]=1,q.push(to[i]);
prex[to[i]]=x;
pres[to[i]]=i;
}
}
return level[t]<0;
}
inline void dfs()
{
int f=inf;
for(register int i=t;i!=s;i=prex[i])chkmin(f,cap[pres[i]]);
for(register int i=t;i!=s;i=prex[i])ans+=f*was[pres[i]],cap[pres[i]]-=f,cap[pres[i]^1]+=f;
}
int main()
{
read(n);read(m);read(k);
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)read(G[i][j]),ans+=G[i][j];
for(register int i=1;i<=k;++i)
{
int x,y;read(x);read(y);
T[x][y]=1;
}
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
if((i+j)&1)
{
M[1][i][j]=++tot,M[2][i][j]=++tot;
if(!T[i][j])insert(M[1][i][j],M[2][i][j],1,-G[i][j]);
}
else M[((i&1)?0:3)][i][j]=++tot;
s=++tot,t=++tot;
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
if(T[i][j])continue;
else if((i+j)&1^1)
{
if(i&1)
{
if(j!=1&&!T[i][j-1])insert(M[0][i][j],M[1][i][j-1],1,0);
if(j!=n&&!T[i][j+1])insert(M[0][i][j],M[1][i][j+1],1,0);
if(i!=1&&!T[i-1][j])insert(M[0][i][j],M[1][i-1][j],1,0);
if(i!=n&&!T[i+1][j])insert(M[0][i][j],M[1][i+1][j],1,0);
insert(s,M[0][i][j],1,0);
}
else
{
if(j!=1&&!T[i][j-1])insert(M[2][i][j-1],M[3][i][j],1,0);
if(j!=n&&!T[i][j+1])insert(M[2][i][j+1],M[3][i][j],1,0);
if(i!=1&&!T[i-1][j])insert(M[2][i-1][j],M[3][i][j],1,0);
if(i!=n&&!T[i+1][j])insert(M[2][i+1][j],M[3][i][j],1,0);
insert(M[3][i][j],t,1,0);
}
}
while(bfs()&&m--)dfs();
write(ans,'\n');
return 0;
}

【刷题】洛谷 P4142 洞穴遇险的更多相关文章

  1. 2018.10.30 一题 洛谷4660/bzoj1168 [BalticOI 2008]手套——思路!问题转化与抽象!+单调栈

    题目:https://www.luogu.org/problemnew/show/P4660 https://www.lydsy.com/JudgeOnline/problem.php?id=1168 ...

  2. AC日记——大爷的字符串题 洛谷 P3709

    大爷的字符串题 思路: 莫队,需开O2,不开50: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20000 ...

  3. Mychael原创题 洛谷T23923 Mychaelの水题 【题解】

    原题链接 题目大意: 有来自三个地区的人各a,b,c位,他们排成了一排.请问有多少种不同类型的排法,使得相邻的人都来自不同的地区 \(a,b,c<=200\) 答案取模 题解 弱弱的标程解法 设 ...

  4. 最短路径Dijkstra算法模板题---洛谷P3371 【模板】单源最短路径(弱化版)

    题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入格式 第一行 ...

  5. 洛谷P5098 洞穴里的牛之三

    题目 贪心,可以用分类讨论的方法,可以得出如果\(n^2\)枚举则会过不了,而我们观察原题中的式子,有: \(∣x1−x2∣+∣y1−y2∣\) 发现式子中的绝对值很恶心,而考虑如果没有绝对值的话会有 ...

  6. [网络流24题] 洛谷P2761 软件补丁问题

    题意:某公司发现其研制的一个软件中有 n个错误,随即为该软件发放了一批共 m 个补丁程序.对于每一个补丁 i ,都有 2 个与之相应的错误集合 B1(i)和 B2(i),使得仅当软件包含 B1(i)中 ...

  7. 高精度加法——经典题 洛谷p1601

    题目背景 无 题目描述 高精度加法,x相当于a+b problem,[b][color=red]不用考虑负数[/color][/b] 输入输出格式 输入格式: 分两行输入a,b<=10^500 ...

  8. 用Python写算法题--洛谷P1149 火柴棒等式

    题目 题目来源 P1149 火柴棒等式,https://www.luogu.org/problem/P1149 题目描述 给你n根火柴棍,你可以拼出多少个形如"A+B=C"的等式? ...

  9. dijkstra模板题 洛谷1339 邻接图建边

    题目链接:https://www.luogu.com.cn/problem/P1339 朴素dijkstra算法的复杂度是O(n^2),用堆优化的dijkstra复杂度是O(nlogn)的.在本题中前 ...

随机推荐

  1. 探寻ASP.NET MVC鲜为人知的奥秘(1):对LESS的支持

    在ASP.NET MVC3中(从那时开始),我们拥有了对js和css等文件的捆绑(Bundling)和压缩(Minification)的能力,这是ASP.NET性能优化工作的一部分. 想一下很久以前, ...

  2. Entity Framework for Oracle 基本配置

    1.需要安装ODAC 如果不安装ODAC,在数据源连接的配置中,看不到Oracle的选项 我下载安装的组件是32-bit Oracle Data Access Components (ODAC)  w ...

  3. 八、EnterpriseFrameWork框架基础功能之自定义报表

    本章写关于框架中的“自定义报表”,类似上章“字典管理”也是三部分功能组成,包括配置报表.对报表按角色授权.查看报表:其核心思想就是实现新增一个报表而不用修改程序代码.不用升级,只需要编写一个存储过程, ...

  4. PHP:Iterator(迭代器)接口和生成器

    迭代器 可在内部迭代自己的外部迭代器或类的接口.详情:http://php.net/manual/zh/class.iterator.php 接口摘要 Iterator extends Travers ...

  5. Android 自动化测试及性能数据采集的 Python 脚本

    文主要介绍一个基于 uiautomator2 封装的一个 Python 库 android-catcher ,该库的功能主要有对 Android 设备进行 UI 自动化测试 和 采集手机性能数据 ,适 ...

  6. 数据库sql优化总结之2-百万级数据库优化方案+案例分析

    项目背景 有三张百万级数据表 知识点表(ex_subject_point)9,316条数据 试题表(ex_question_junior)2,159,519条数据 有45个字段 知识点试题关系表(ex ...

  7. 136.只出现一次的数字 leetcode ^运算符 JavaScript解法

    leetcode上的一道题简单题 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间 ...

  8. vs2017 asp.net FriendlyUrls 新特性

    这个包如何使用呢?其实很简单,只需将nuget包添加到项目中,再调用routes.EnableFriendlyUrls(),你就可以通过/Foo来访问/Foo.aspx了!你也能够利用URL片段将更多 ...

  9. 雅虎工程师提供的CSS初始化示例代码

    body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,b ...

  10. HDU 2012 FZU 1756关于素数的一些水题

    HDU 2012 素数判定 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...