2326. 王者之剑(网络流,最小割,最大权独立集,最小点权覆盖)

news2024/9/21 16:36:44

活动 - AcWing

给出一个 n×m 网格,每个格子上有一个价值 vi,j 的宝石。

Amber 可以自己决定起点,开始时刻为第 0 秒。

以下操作,在每秒内按顺序执行。

  1. 若第 i 秒开始时,Amber 在 (x,y),则 Amber 可以拿走 (x,y) 上的宝石。
  2. 在偶数秒时(i 为偶数),则 Amber 周围 4 格的宝石将会消失。
  3. 若第 i 秒开始时,Amber 在 (x,y),则在第 (i+1) 秒开始前,Amber 可以马上移动到相邻的格子 (x+1,y),(x−1,y),(x,y+1),(x,y−1) 或原地不动 (x,y)。

求 Amber 最多能得到多大总价值的宝石。

aaa.png

上图给出了一个 2×2 的网格的例子。

在第 0 秒,首先选择 B2 进入,取走宝石 3;由于是偶数秒,周围的格子 A2,B1 的宝石 1,2 消失;向 A2 走去。

在第 1 秒,由于 A2 的宝石已消失,无宝石可取;向 A1 走去。

在第 2 秒,取走 A1 的宝石 4。

全程共取得 2 块宝石:宝石 3 和宝石 4。

输入格式

第一行包含两个整数 n,m。

接下来 n 行,每行包含 m 个整数,用来描述宝石价值矩阵。其中第 i 行第 j 列的整数表示 vi,j。

输出格式

输出可拿走的宝石最大总价值。

数据范围

1≤n,m≤100
1≤vi,j≤1000

输入样例:
2 2
1 2
2 1
输出样例:
4

解析: 

最大权独立集=总权值 - 最小权点覆盖

性质:

(1)只能在偶数秒拿宝石

(2)不可能拿走相邻格子上的宝石

如果将相邻两个格子之间都连一条边,则能拿的宝石一定是一个独立集。而每个格子上都有一个权值,又是求获得宝石的最大值,可以发现本题已经非常像最大权独立集问题。

到此已经能将任意一个合法方案对应到二分图中的一个独立集。但是还需要证明任意一个二分图中的独立集都能对应到一个合法方案。其实对于任意一个独立集都能构造出一个合法方案,可以从最左上角的一个有宝石的格子开始走,依次去取别的宝石,假设当前距离下一个宝石还剩两步,停下来判断一下,如果当前是偶数秒,直接走过去拿宝石,如果当前是奇数秒,原地停一秒再走过去拿宝石。且保证每次都优先取最近的宝石。这样的行走方案一定能将独立集中的所有宝石拿走,可以自行按照以上思路证明,这里的构造方式非常多,只要掌握好停顿一秒的精髓就能随便构造。

由此得出任意一个合法方案和任意一个独立集都是一一对应的,因此要想求最大能取的宝石价值就等价于求最大权独立集,而最大权独立集 = 总权值 − 最小权点覆盖集。

 最大权点独立集的相关概念

 独立集: 给定一个一般图 G(V,E),选出图中的某一个点集,使得选出的所有点之间不存在边,则将这个点集称为原图的 独立集

-------------------------------------------------------------------------------------------------------------------

最大权独立集: 给定一个有向图 G(V,E),每个点上有一个非负权值,而图中权值和最大的独立集称为 最大权独立集

-------------------------------------------------------------------------------------------------------------------

如何求最大权独立集:

最大权独立集和最小权点覆盖集问题一样,在一般情况下都是一个 NP 完全问题(NPC 问题),只能用爆搜来解决,但是在二分图中却具有非常高效的特殊做法。

结论:最大权点独立集 = 所有点的总权值 − 最小权点覆盖集

若整个点集是 V,点覆盖集是 V1,那么补集就是 V2=V−V1。

这里有一个性质,任意一个点覆盖集的补集都一定是独立集。这里进一步证明这个性质。可以用反证法,假设点覆盖集 V1 的补集 V2 不是独立集,说明 V2 中存在两个点 u,v 之间存在一条边 (u,v)。由于 V1 同样是 V2 的补集,说明 V1 中一定不包含 u,v 这两个点,那么 (u,v) 这条边的两个点就都不在 V1 中,即 V1 不是一个点覆盖集,与条件矛盾,反证得出任意一个点覆盖集的补集都是一个独立集。

以上性质反过来,任意一个独立集的补集都一定是点覆盖集。同样用反证法,假设独立集 V2 的补集 V1 不是点覆盖集,就必然存在一条边 (u,v),使得这条边的两个点 u,v 都不在 V1,即一定在 V2 中,也就说明 V2 中存在两个点 u,v 之间是有边的,所以 V2 就不是一个独立集,反证得出任意一个独立集的补集都是一个点覆盖集。

可以发现独立集和点覆盖集之间是存在补集这样一个对应关系的,然后看一下两者之间的数量关系,数量关系就非常明显了,因为 V1 和 V2 互为补集,所以两个集合的权值总和就等于所有点的权值和,即 w(V1)+w(V2)=w(V),而 w(V) 是一个固定值,因此想让 w(V2) 取最大,w(V1) 就必然取到最小,因此要想求最大全独立集,只需要求一下最小权点覆盖集,最小权点覆盖集的补集就是最大权独立集,由此得证结论。

——————————————————————————————————————

作者:小小_88
链接:https://www.acwing.com/file_system/file/content/whole/index/content/6381812/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

(非常棒的作者,建议看原题解)

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 1e4 + 10, M = (2e4 + N ) * 2 + 10, INF = 0x3f3f3f3f;
int n, m, S, T;
int h[N], e[M], f[M], ne[M], idx;
int q[N], d[N], cur[N];

int get(int a, int b) {
	return (a - 1) * m + b;
}

void add(int a, int b, int c) {
	e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx++;
	e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx++;
}

bool bfs() {
	int hh = 0, tt = 0;
	memset(d, -1, sizeof d);
	q[0] = S, d[S] = 0, cur[S] = h[S];
	while (hh <= tt) {
		int t = q[hh++];
		for (int i = h[t]; i != -1; i = ne[i]) {
			int j = e[i];
			if (d[j] == -1 && f[i]) {
				d[j] = d[t] + 1;
				cur[j] = h[j];
				if (j == T)return 1;
				q[++tt] = j;
			}
		}
	}
	return 0;
}

int find(int u, int limit) {
	if (u == T)return limit;
	int flow = 0;
	for (int i = cur[u]; i != -1 && flow < limit; i = ne[i]) {
		int j = e[i];
		cur[u] = i;
		if (d[j] == d[u] + 1 && f[i]) {
			int t = find(j, min(f[i], limit - flow));
			if (!t)d[j] = -1;
			f[i] -= t, f[i ^ 1] += t, flow += t;
		}
	}
	return flow;
}

int dinic() {
	int ret = 0, flow;
	while (bfs())while (flow = find(S, INF))ret += flow;
	return ret;
}

int main() {
	int dx[] = { 0,0,1,-1 }, dy[] = { 1,-1,0,0 };
	cin >> n >> m;
	S = 0, T = m * n + 1;
	memset(h, -1, sizeof h);
	int tot = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 1,a; j <= m; j++) {
			scanf("%d", &a);
			if (i + j & 1) {
				add(S, get(i, j), a);
				for (int k = 0; k < 4; k++) {
					int x = i + dx[k], y = j + dy[k];
					if (x > 0 && x <= n && y > 0 && y <= m)
						add(get(i, j), get(x, y), INF);
				}
			}
			else add(get(i, j), T, a);
			tot += a;
		}
	}
	printf("%d\n", tot - dinic());
	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1481645.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring.factories的常用配置项

概述 spring.factories 实现是依赖 spring-core 包里的 SpringFactoriesLoader 类&#xff0c;这个类实现了检索 META-INF/spring.factories 文件&#xff0c;并获取指定接口的配置的功能。 Spring Factories机制提供了一种解耦容器注入的方式&#xff0c;帮助外部包&am…

qsort函数 结构体比较(strcmp函数(比较字符串的大小))

strcmp函数应用于qsort函数&#xff0c;排序创建函数指针时比较字符串大小。 这里我创建了一个简单的学生结构体&#xff0c;这个结构体只包含名字跟年龄两个信息。 在创建函数指针cmp_stu_age后&#xff0c;进行年龄大小比较&#xff0c;强制类型转换成stu*。 int cmp_stu_ag…

报错问题解决django.db.utils.OperationalError: (1049, “Unknown database ‘ mxshop‘“)

开发环境&#xff1a;ubuntu22.04 pycharm 功能&#xff1a;django连接使用mysql数据库&#xff0c;各项配置看似正常 报错&#xff1a; django.db.utils.OperationalError: (1049, "Unknown database mxshop") 分析检查原因&#xff1a; Setting的配置文件内&…

【JavaEE】_HttpServletResponse类

目录 1. 核心方法 2. 关于setStatus(400)与sendError 2.1 setStatus(400) 2.2 sendError 3. setHeader方法 4. 构造重定向响应 4.1 使用setHeader和setStatus实现重定向 4.2 使用sendRedirect实现重定向 本专栏已有文章介绍HttpServlet和HttpServletRequest类&#…

使用Python语言实现一个基于动态数组的序列队列

一、动态数组的实现 首先&#xff0c;我们需要创建一个DynamicArray类&#xff0c;该类将管理我们的动态数组。 动态数组能够动态地调整其大小&#xff0c;以容纳更多的元素。 目录 一、动态数组的实现 代码示例&#xff1a; 二、序列队列的实现 接下来&#xff0c;我…

【rust】10 project、crate、mod、pub、use、项目目录层级组织、概念和实战

文章目录 一、项目目录层级组织概念1.1 cargo new 创建同名 的 Project 和 crate1.2 多 crate 的 package1.3 mod 模块1.3.1 创建嵌套 mod1.3.2 mod 树1.3.3 用路径引用 mod1.3.3.1 使用绝对还是相对? 1.3.4 代码可见性1.3.4.1 pub 关键字1.3.4.2 用 super 引用 mod1.3.4.3 用…

Mathtype安装时word启动显示“文件未找到:MathPage.WLL”

背景 由于老板布置的临时工作&#xff0c;需要安装Mathtype&#xff0c;但尝试了3个不同的版本后&#xff08;每次都卸载干净了&#xff09;&#xff0c;均未能成功安装&#xff0c;出现的报错3个版本各不相同&#xff1a; ①解压安装过程中失败&#xff08;这个版本不再尝试…

数据可视化原理-腾讯-热力图

在做数据分析类的产品功能设计时&#xff0c;经常用到可视化方式&#xff0c;挖掘数据价值&#xff0c;表达数据的内在规律与特征展示给客户。 可是作为一个产品经理&#xff0c;&#xff08;1&#xff09;如果不能够掌握各类可视化图形的含义&#xff0c;就不知道哪类数据该用…

MySQL、高级SQL操作

学习数据库的目的 岗位需求、大数据时代、被迫需求&#xff0c;存数据 数据库是所有软件体系中最核心的存在 数据库 DB DB dataBase 数据仓库&#xff0c;软件&#xff0c;安装在window、linux、mac上&#xff0c;可以存储大量数据&#xff0c;500w 作用&#xff1a;存储数据…

docker的数据卷和docker的自定义镜像

docker的数据卷和docker的自定义镜像 1.docker的数据卷1.1创建 docker volume create 数据卷名称1.2 查看数据卷docker volume ls1.3 删除一个volume 2.将宿主机的目录与容器的目录进行挂载&#xff0c;实现数据共享2.1数据卷相互共享 3.自定义镜像3.1编辑Dockerfiile文件 vim …

位运算第二弹

力扣191.位1的个数 public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {int ret0;while(n!0){n(n&n-1);ret;}return ret;} } 推荐是自己去手动推一下&#xff0c;深刻理解一下&#xff0c;什么叫做最右侧的1。 力扣338.…

3694-51-7,3,5-Dinitro-1,2-phenylenediamine,合成其他化合物的重要中间体

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;3694-51-7&#xff0c;3,5-Dinitro-1,2-phenylenediamine&#xff0c;3,5-二硝基-1,2-苯二胺;3,5-二硝基苯-1,2-二胺 一、基本信息 【产品简介】&#xff1a;3,5-Dinitro-1,2-phenylenediamine, with the molecular…

MySql出现无法正常启动(0x000007b)的快速解决

目录 1.背景介绍 2.解决方案 1.背景介绍 昨天在清理电脑内存空间的时候&#xff0c;不小心将一些重要的系统组件删除&#xff0c;导致无法正常启动mysql&#xff0c;一开始是提示经过msvcp120.dll&#xff0c;于是找到下载dll的网站将组件补充进system&#xff0c;但随后又提…

【办公类-25-01】20240304 UIBOT上传 ”班级主页-信息窗“

一、背景需求&#xff1a; 本学期制作了 “信息窗主题说明”合并A4内容 【办公类-22-07】周计划系列&#xff08;3-1&#xff09;“信息窗主题知识&#xff08;提取&#xff09;” &#xff08;2024年调整版本&#xff09;-CSDN博客文章浏览阅读797次&#xff0c;点赞7次&…

渗压计使用中的常见问题及其解决方案

渗压计作为一种用于测量土壤或岩石中孔隙水压力的重要工具&#xff0c;在地质工程和水文学领域具有广泛的应用。然而&#xff0c;在实际使用过程中&#xff0c;渗压计可能会遇到多种常见问题&#xff0c;这些问题不仅影响测量精度&#xff0c;还可能对设备本身造成损害。本文将…

【力扣】207.课程表(图)

依旧还是有关于图的题目&#xff0c;这次不一样的点在于题目并没有明确的给出他是图的题目的形式&#xff0c;而是说让你根据其题目意思来进行操作。 首先&#xff0c;就是搞清楚题目的意思。假设你想学习A课程&#xff0c;那就是必须先学习B课程&#xff0c;但是这里给出的例…

消息队列+更新DB极易引发的DB并发修改bug

背景 我们在生产系统中和其他系统进行交互时一般都会通过消息队列来解耦生产者和消费者&#xff0c;然后通过每个使用方消费消息队列的消息的方式来完成消息的消费&#xff0c;并且一般来说我们消费消息后极有可能会操作DB&#xff0c;不过这种方式如果处理不够仔细&#xff0…

Linux——进程控制(一)进程的创建与退出

目录 一、进程创建 1.写时拷贝 2.创建多个进程 二、进程终止 1.main函数的返回值 2.bash中的$? 3.自定义退出码 4.C语言的错误码 5.错误码与退出码的区别 6.代码异常终止 7.exit函数 8.总结 一、进程创建 在之前&#xff0c;我们学过linux中的非常重要的函数——…

全网爆火的 MBTI 测试,是隐藏的割韭菜工具?

小伙伴们&#xff0c;谁能想到&#xff0c;作为一名冲浪老手&#xff0c;果子在网上又被骗了。 事情是这样的&#xff0c;前几天&#xff0c;我刷微博&#xff0c;看到一个推荐&#xff0c;大概如下图&#xff0c;是一个 MBTI 人格测试。 MBTI 测试&#xff0c;果子早就做过了…

【前端素材】推荐优质在线电影院商城电商网页Hyper平台模板(附源码)

一、需求分析 1、系统定义 在线电影商城是指一个通过互联网提供电影服务的平台&#xff0c;用户可以在该平台上浏览电影资源、租借或购买电影&#xff0c;以及观看在线影片。 2、功能需求 在线电影商城是指一个通过互联网提供电影服务的平台&#xff0c;用户可以在该平台上…