【刷题】洛谷 P4142 洞穴遇险
题目背景
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 洞穴遇险的更多相关文章
- 2018.10.30 一题 洛谷4660/bzoj1168 [BalticOI 2008]手套——思路!问题转化与抽象!+单调栈
题目:https://www.luogu.org/problemnew/show/P4660 https://www.lydsy.com/JudgeOnline/problem.php?id=1168 ...
- AC日记——大爷的字符串题 洛谷 P3709
大爷的字符串题 思路: 莫队,需开O2,不开50: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20000 ...
- Mychael原创题 洛谷T23923 Mychaelの水题 【题解】
原题链接 题目大意: 有来自三个地区的人各a,b,c位,他们排成了一排.请问有多少种不同类型的排法,使得相邻的人都来自不同的地区 \(a,b,c<=200\) 答案取模 题解 弱弱的标程解法 设 ...
- 最短路径Dijkstra算法模板题---洛谷P3371 【模板】单源最短路径(弱化版)
题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入格式 第一行 ...
- 洛谷P5098 洞穴里的牛之三
题目 贪心,可以用分类讨论的方法,可以得出如果\(n^2\)枚举则会过不了,而我们观察原题中的式子,有: \(∣x1−x2∣+∣y1−y2∣\) 发现式子中的绝对值很恶心,而考虑如果没有绝对值的话会有 ...
- [网络流24题] 洛谷P2761 软件补丁问题
题意:某公司发现其研制的一个软件中有 n个错误,随即为该软件发放了一批共 m 个补丁程序.对于每一个补丁 i ,都有 2 个与之相应的错误集合 B1(i)和 B2(i),使得仅当软件包含 B1(i)中 ...
- 高精度加法——经典题 洛谷p1601
题目背景 无 题目描述 高精度加法,x相当于a+b problem,[b][color=red]不用考虑负数[/color][/b] 输入输出格式 输入格式: 分两行输入a,b<=10^500 ...
- 用Python写算法题--洛谷P1149 火柴棒等式
题目 题目来源 P1149 火柴棒等式,https://www.luogu.org/problem/P1149 题目描述 给你n根火柴棍,你可以拼出多少个形如"A+B=C"的等式? ...
- dijkstra模板题 洛谷1339 邻接图建边
题目链接:https://www.luogu.com.cn/problem/P1339 朴素dijkstra算法的复杂度是O(n^2),用堆优化的dijkstra复杂度是O(nlogn)的.在本题中前 ...
随机推荐
- AngularJS中Directive指令系列
近段时间在研究Angular中的directive用法,打算写个系列.以官方文档为主.并参考诸多教程.加上自己的思考. 基本概念及用法 scope属性的使用. &, <, =, @ 符 ...
- loj2538 「PKUWC 2018」Slay the Spire
pkusc 快到了--做点题涨涨 rp. ref我好菜啊QAQ. 可以发现期望只是一个幌子.我们的目的是:对于所有随机的选择方法(一共 \(\binom{2n}{m}\)种),这些选择方法都最优地打出 ...
- Linux TCP/IP调优参数 /proc/sys/net/目录
所有的TCP/IP调优参数都位于/proc/sys/net/目录. 例如, 下面是最重要的一些调优参数,后面是它们的含义: /proc/sys/net/core/rmem_default " ...
- React Native 【学习总结】-【常用命令】
前言 刚接触RN,相信很多人无从下手,不知道下一步要干什么,能干什么,本次学习围绕这个问题,将RN的常用命令总结一下,帮助你快速上手 架构理解 光知道命令的作用,远远不够,如果知道命令背后的意义,才能 ...
- 关于cnblog.com的用户体验
首先我自己目前是一个学生党,每天在博客园上就上发布一些自己做的东西以及老师布置的作业,还能在上面学习很多别人的一些好的列子,我就希望博客园能够很好地为我们这些学生服务,当我们用它时能够很好地达到我们的 ...
- linshi12
#include<iostream> using namespace std; int main(){ int a[50]; a[1]=5; int i; for(i=2;;i++){ a ...
- 关于String和StringBuffer的原理
public class Foo {2. public static void main (String [] args) {3. StringBuffer a = new Strin ...
- Spring中jdbc Template使用
http://1358440610-qq-com.iteye.com/blog/1826816
- TCP系列46—拥塞控制—9、SACK下的快速恢复与Limited transmit
一.概述 1.SACK下的特殊处理过程 SACK下的拥塞控制处理是linux中拥塞控制的实现依据,再次强调一遍RFC6675的重要性,linux中拥塞控制主体框架的实现是与RFC6675一致的,所以如 ...
- 蜗牛慢慢爬 LeetCode 2. Add Two Numbers [Difficulty: Medium]
题目 You are given two non-empty linked lists representing two non-negative integers. The digits are s ...