最小路径覆盖

给n个自然数,要求穿在尽量少的柱子上,条件是i+j是个完全平方数。

这是二分图问题,X集合为1...n, Y集合也为1...n。那么如果该二分图的最大匹配数为m,则结果就是n-m.

因为:

路径覆盖中每个简单路径除最后一结点外都有唯一后继和它对应,因此匹配数就是非路径结尾的结点数。所以说匹配数最大,就是说非结尾点最多,由于总数为n,那么结尾数就最少喽,正好对应了柱子数啊!!!

### 最小路径覆盖问题概述 最小路径覆盖问题是图论中的一个重要概念,主要针对有向无环图 (DAG),目标是在给定的 DAG 中找到最少数量的互不相交路径,使得这些路径能够覆盖所有的顶点。这意味着每个顶点恰好属于一条路径。 ### 转化为二分图最大匹配问题 为了有效解决最小路径覆盖问题,可以将原始的有向无环图转换成一个对应的二分图。具体做法如下: - 对于原图中的每一个节点 \( v \),创建两个新节点 \( u_v \) 和 \( w_v \),分别位于二分图的不同部分; - 如果存在从节点 \( i \) 到节点 \( j \) 的边,则在新的二分图中连接 \( u_i \) 和 \( w_j \)[^1]; 这样构建出来的二分图保留了原有向图的所有结构特性,并且允许利用成熟的算法工具对其进行分析处理。 ### 使用匈牙利算法解 一旦完成了上述转化过程之后,就可以采用诸如匈牙利算法这样的经典技术来寻找这个二分图内的最大匹配数 M 。对于任意一张 n 个结点构成的 DAG ,其最小路径数目等于总顶点数减去所得到的最大匹配数加一(\(n-M\))。这是因为每一对成功配对成功的顶点实际上代表了一条完整的路径,在此基础上再考虑未被匹配到的孤立点即可得出最终结果。 ```cpp // C++ code snippet demonstrating the conversion and solving process using Hungarian algorithm. #include <iostream> using namespace std; bool dfs(int node, vector<vector<int>>& graph, vector<bool>& visited, vector<int>& match){ for(auto& next : graph[node]){ if(!visited[next]){ visited[next]=true; if(match[next]==-1 || dfs(match[next],graph,visited,match)){ match[next]=node; return true; } } } return false; } int maxMatching(vector<vector<int>> &G){ int V=G.size(); vector<int> match(V,-1); int result=0; for(int u=0;u<V;++u){ vector<bool> seen(V,false); if(dfs(u,G,seen,match)) ++result; } return result/2; // Each edge is counted twice hence divide by two } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值