「网络流 24 题」魔术球 【最小路径覆盖】

2024-05-08 21:20

本文主要是介绍「网络流 24 题」魔术球 【最小路径覆盖】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

「网络流 24 题」魔术球

1

注意这里的球是依次放置,也就是说如果当前放到第 i i i 号球,那么 1 → i − 1 1 \rarr i - 1 1i1 号球都已经放好了,否则可以放无数个球

思路

首先我们对于 i < j 且 i + j = 完全平方数 i < j 且 i + j = 完全平方数 i<ji+j=完全平方数 连边: i → j i \rarr j ij
并且我们假设当前我们要构造答案 x x x,也就是说 [ 1 , x ] [1,x] [1,x] 号球我们都要放好
那么对于这张有 x x x 个点的有向无环图,我们等价于要找一些路径去覆盖整张图,并且路径数越少越好!同一路径上的点就表示我们将这些球按顺序放在同一柱子上

我们可以从小到大枚举答案 n n n,并且在之前的基础上添加新的有向边 i → n i f i + n = 完全平方数 i \rarr n \quad if \quad i + n = 完全平方数 inifi+n=完全平方数,然后跑一个最小路径覆盖,判断所需的柱子数是否小于等于给定的柱子数即可

时间复杂度: O ( n ⋅ ( n + n m ) ) , m O(n \cdot (n + nm)),m O(n(n+nm))m 为边数

// Problem: #6003. 「网络流 24 题」魔术球
// Contest: LibreOJ
// URL: https://loj.ac/p/6003
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 
#define ull unsigned long longconst int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;typedef long long ll;const int N = 2500;std::vector<int> match; //match[i]表示每个右点i当前匹配的左点
std::vector<bool> used; //当前轮 右点 i 是否被预定
std::vector<int> g[N];bool dfs(int l){ //为当前左点 l 寻找匹配for(auto r : g[l])if(!used[r]){ //如果当前轮右点r还没有被预订used[r] = true; //预定if(!match[r] || dfs(match[r])){match[r] = l;return true;
//(1)如果右点 r 还没有配对
//(2)右点 r 已经配对,尝试更换其原配左点}}return false;
}int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int k;std::cin >> k;int cnt = 0;fore(n, 1, N){match.assign(n + 1, 0);fore(i, 1, n){ //在原先的基础上加边int w = i + n;int rt = sqrt(w);if(rt * rt != w)	continue;g[i].push_back(n);}int num = 0; //最大匹配数fore(i, 1, n + 1){used.assign(n + 1, false);num += dfs(i);}num = n - num; //最小路径覆盖if(num > k)	break; //柱子不够cnt = n;}std::cout << cnt << endl;std::vector<int> nxt(cnt + 1, 0);std::vector<bool> head(cnt + 1, true);fore(v, 1, cnt + 1){int u = match[v];if(!u)	continue;head[v] = false;nxt[u] = v;}fore(i, 1, cnt + 1){if(!head[i])	continue;int u = i;while(nxt[u]){std::cout << u << ' ';u = nxt[u];}std::cout << u << endl;}return 0; 
}

这篇关于「网络流 24 题」魔术球 【最小路径覆盖】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

python获取当前文件和目录路径的方法详解

《python获取当前文件和目录路径的方法详解》:本文主要介绍Python中获取当前文件路径和目录的方法,包括使用__file__关键字、os.path.abspath、os.path.realp... 目录1、获取当前文件路径2、获取当前文件所在目录3、os.path.abspath和os.path.re

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];