2020年11月25日提高组 D 不稳定的导弹系统 JZOJ 5057【GDSOI2017模拟4.13】炮塔

2023-10-13 00:59

本文主要是介绍2020年11月25日提高组 D 不稳定的导弹系统 JZOJ 5057【GDSOI2017模拟4.13】炮塔,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

R e s u l t Result Result

...


H y p e r l i n k Hyperlink Hyperlink

洛谷
炮塔


D e s c r i p t i o n Description Description

一个 n × m n\times m n×m的网格上有若干个炮台,每个炮台有一个固定的方向,它可以选择打掉这个方向上任意一个点,并获得这个点上的价值(每个点的至多被获取一次价值,保证一个炮台打不到另一个炮台)

若炮台路径不相交,求最大代价

数据范围: n , m ≤ 50 n,m\leq 50 n,m50


S o l u t i o n Solution Solution

这么小的数据范围不是 d p dp dp就是网络流啦(显然考虑网络流嘛,毕竟这是一个取舍问题)

但是正向求貌似很难搞炮台路径相交这个恶心的点,我们考虑用可能的答案减去不合法的
显然,若我们不考虑路径相交,答案就是每个炮台在攻击路径上取个最大值就好了

若考虑路径相交,说明每台炮不能那么舒服的打到价值最高的点,而是考虑你打了某个点会对答案造成的影响
显然我们是可以预处理出来每个炮台打到每个点的价值,然后将路径看做从纵向的走向横向的(就是划分出来源点和汇点分别相连的点)

由于路径不能相交,换句话说就是没有通路,自然想到了最小割
不过这样做处理不了某种恶心人的情况,就是虽然我这条是通路,但实际上是合法的,如下图
....
针对左图这种情况,我们显然可以选择割掉右图中的这三条边就可以合法
但是在网络流中,它还会多割一条边使得图不连通,就恶心到了我们

解决的方法也很简单,考虑拆点使得横纵分开即可

时间复杂度: O ( f l o w ( n 2 m 2 ) ) O(flow(n^2m^2)) O(flow(n2m2))


C o d e Code Code
#include<queue>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define p(i,j) (((i-1)*m+j)*2)
#define q(i,j) (((i-1)*m+j)*2-1)
#define N 5100
using namespace std;int n,m,a[51][51],ans,s,t,sum;
struct node{int next,to,w;}e[N<<2];
int l[N],tot,d[N];
bool vis[N];
inline void add(int u,int v,int w)
{e[tot]=(node){l[u],v,w};l[u]=tot++;e[tot]=(node){l[v],u,0};l[v]=tot++;return;
}
inline bool bfs()
{memset(d,-1,sizeof(d));queue<int>q;d[s]=0;q.push(s);while(q.size()){int x=q.front();q.pop();for(int i=l[x];~i;i=e[i].next){int y=e[i].to;if(e[i].w&&d[y]==-1){d[y]=d[x]+1;q.push(y);if(y==t) return true;}}}return false;
}
int dfs(int x,int flow)
{if(x==t||!flow) return flow;int rest=0,k=0,f=0;for(int i=l[x];~i;i=e[i].next){int y=e[i].to;if(d[x]+1==d[y]&&e[i].w){f=dfs(y,min(flow-rest,e[i].w));if(!f) d[y]=-1;e[i].w-=f;rest+=f;e[i^1].w+=f;}}if(!rest) d[x]=-1;return rest;
}
void dinic()
{while(bfs()) sum-=dfs(s,1e9);return;
}
inline LL read()
{char c;LL d=1,f=0;while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;return d*f;
}
signed main()
{memset(l,-1,sizeof(l));n=read();m=read();s=0;t=n*m*2+1;for(register int i=1;i<=n;i++) for(register int j=1;j<=m;j++) a[i][j]=read(),add(p(i,j),q(i,j),1e9);for(register int i=1;i<=n;i++) for(register int j=1;j<=m;j++) if(a[i][j]<0){int mx=0;if(a[i][j]==-1) {add(s,p(i,j),1e9);for(register int k=i;k>=1;k--) mx=max(a[k][j],mx);for(register int k=i;k>=2;k--) add(p(k,j),p(k-1,j),mx-max(a[k][j],0));}if(a[i][j]==-2){add(s,p(i,j),1e9);for(register int k=i;k<=n;k++) mx=max(a[k][j],mx);for(register int k=i;k<n;k++) add(p(k,j),p(k+1,j),mx-max(a[k][j],0));}if(a[i][j]==-3){add(q(i,j),t,1e9);for(register int k=j;k>=1;k--) mx=max(a[i][k],mx);for(register int k=j;k>=2;k--) add(q(i,k-1),q(i,k),mx-max(a[i][k],0));}if(a[i][j]==-4){add(q(i,j),t,1e9);for(register int k=j;k<=m;k++) mx=max(a[i][k],mx);for(register int k=j;k<m;k++) add(q(i,k+1),q(i,k),mx-max(a[i][k],0));}sum+=mx;}		dinic();printf("%lld",sum);
}

这篇关于2020年11月25日提高组 D 不稳定的导弹系统 JZOJ 5057【GDSOI2017模拟4.13】炮塔的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/199669

相关文章

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

跨系统环境下LabVIEW程序稳定运行

在LabVIEW开发中,不同电脑的配置和操作系统(如Win11与Win7)可能对程序的稳定运行产生影响。为了确保程序在不同平台上都能正常且稳定运行,需要从兼容性、驱动、以及性能优化等多个方面入手。本文将详细介绍如何在不同系统环境下,使LabVIEW开发的程序保持稳定运行的有效策略。 LabVIEW版本兼容性 LabVIEW各版本对不同操作系统的支持存在差异。因此,在开发程序时,尽量使用

键盘快捷键:提高工作效率与电脑操作的利器

键盘快捷键:提高工作效率与电脑操作的利器 在数字化时代,键盘快捷键成为了提高工作效率和优化电脑操作的重要工具。无论是日常办公、图像编辑、编程开发,还是游戏娱乐,掌握键盘快捷键都能带来极大的便利。本文将详细介绍键盘快捷键的概念、重要性、以及在不同应用场景中的具体应用。 什么是键盘快捷键? 键盘快捷键,也称为热键或快捷键,是指通过按下键盘上的一组键来完成特定命令或操作的方式。这些快捷键通常涉及同

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

如何提高 GitHub 的下载速度

如何提高 GitHub 的下载速度 文章目录 如何提高 GitHub 的下载速度1. 注册账号2. 准备好链接3. 创建仓库4. 在码云上下载代码5. 仓库更新了怎么办 一般来说,国内的朋友从 GitHub 上面下载代码,速度最大是 20KB/s,这种龟速,谁能忍受呢? 本文介绍一种方法——利用“码云”,可以大大提高下载速度,亲测有效。 1. 注册账号 去“码云”注册一