当前位置: 首页 > news >正文

独立网站开发站长之家站长工具

独立网站开发,站长之家站长工具,网站的商桥怎么做,类似wordpress的应用作者推荐 视频算法专题 本文涉及知识点 动态规划汇总 广度优先搜索 状态压缩 LeetCode847 访问所有节点的最短路径 存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号。 给你一个数组 graph 表示这个图。其中,graph[i] 是一个列…

作者推荐

视频算法专题

本文涉及知识点

动态规划汇总
广度优先搜索 状态压缩

LeetCode847 访问所有节点的最短路径

存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号。
给你一个数组 graph 表示这个图。其中,graph[i] 是一个列表,由所有与节点 i 直接相连的节点组成。
返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。
示例 1:
输入:graph = [[1,2,3],[0],[0],[0]]
输出:4
解释:一种可能的路径为 [1,0,2,0,3]
示例 2:
输入:graph = [[1],[0,2,4],[1,3,4],[2],[1,2]]
输出:4
解释:一种可能的路径为 [0,1,4,2,3]
参数范围
n == graph.length
1 <= n <= 12
0 <= graph[i].length < n
graph[i] 不包含 i
如果 graph[a] 包含 b ,那么 graph[b] 也包含 a
输入的图总是连通图

广度优先搜索

需要记录那些节点已经访问,用状态压缩 (1 << i )表示第i个节点已访问。
还要记录此路径的最后节点。
这两个状态相同,后面的路径则相同。 由于是广度优先搜索,所以路径短的先处理,每个状态只会处理一次。
vDis 记录各状态的最短路径数。
que 记录状态。
时间复杂度:O(n2nn) 枚举起点O(n) 枚举状态数O(2^n) 每个状态处理。

核心代码

class Solution {
public:int shortestPathLength(vector<vector<int>>& graph) {m_c = graph.size();m_iMaskCount = 1 << m_c;for (int i = 0; i < m_c; i++){BFS(graph, i);}return m_iRet;}void BFS(vector<vector<int>>& neiBo,int start){vector<vector<int>> vDis(m_c, vector<int>(m_iMaskCount, m_iNotMay));queue<pair<int, int>> que;auto Add = [&](int node, int iPreMask,int iNew){const int iMask = iPreMask | (1 << node);if (vDis[node][iMask] <= iNew ){return ;}vDis[node][iMask] = iNew;que.emplace(node, iMask);};Add( start,0, 0);while (que.size()){auto [preNode, preMask] = que.front();const int iNew = vDis[preNode][preMask]+1;que.pop();for (const auto& next : neiBo[preNode]){Add(next, preMask, iNew);}}for (const auto& v : vDis){m_iRet = min(m_iRet, v.back());}}const int m_iNotMay = 100'000;int m_c, m_iMaskCount;int m_iRet = m_iNotMay;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{	vector<vector<int>> graph;{Solution sln;graph = { {1,2,3},{0},{0},{0} };auto res = sln.shortestPathLength(graph);Assert(res, 4);}{Solution sln;graph = { {1},{0,2,4},{1,3,4},{2},{1,2} };auto res = sln.shortestPathLength(graph);Assert(res, 4);}}

动态规划

节点的距离用多源路径的最短距离。

动态规划的状态表示

mask&(1 << next)表示经过了next节点。
vDis[node][mask] 有以下两种含义:
一, 以node结尾,经过mask指定节点的最短路径经过的节点数。
二,以node结尾,且只经过node节点一次,经过mask指定节点的最短路径经过的节点数。
含义二,如果存在,则是含义二,否则是含义一。 必须枚举所有符合含义二的可能。

动态规划的转移方程

vDis[next][maks|next]= MinSelf n e x t = 0 m c − 1 \Large_{next=0}^{m_c-1} next=0mc1vDis[i][mask]+距离(i,next)
vDis[i][mask] 必须合法,且mask不包括next节点

动态规划的填表顺序

mask从1到大,确保动态规划的无后效性。某路径的编码是mask,经过新节点next后,新编码为iNewMask。则iNewMask-mask = 1 << next
1 << next 恒大于0。

动态规划的初始值

全部为不存在的数

动态规划的返回值

Min j = 0 m c − 1 \Large_{j=0}^{m_c-1} j=0mc1vDis[j].back() -1

证明

将最短路径的重复节点删除,保留任意一个。删除后为: i 1 \Large_1 1 i 2 \Large_2 2 …i n \Large_n n 。任意i k \Large_k k到i k + 1 \Large_{k+1} k+1的路径一定是最短,否则替换成最短。直接枚举,12! 超时。 用动态规划,共2nn种状态,空间复杂度O(2nn),每种状态转移时间复杂度O(n),故总时间复杂度O(2nnn)。

代码

//多源码路径
template<class T, T INF = 1000 * 1000 * 1000>
class CFloyd
{
public:CFloyd(const  vector<vector<T>>& mat){m_vMat = mat;const int n = mat.size();for (int i = 0; i < n; i++){//通过i中转for (int i1 = 0; i1 < n; i1++){for (int i2 = 0; i2 < n; i2++){//此时:m_vMat[i1][i2] 表示通过[0,i)中转的最短距离m_vMat[i1][i2] = min(m_vMat[i1][i2], m_vMat[i1][i] + m_vMat[i][i2]);//m_vMat[i1][i2] 表示通过[0,i]中转的最短距离}}}};vector<vector<T>> m_vMat;
};class Solution {
public:int shortestPathLength(vector<vector<int>>& graph) {m_c = graph.size();m_iMaskCount = 1 << m_c;vector<vector<int>> mat(m_c, vector<int>(m_c, 1000 * 1000 * 1000));for (int i = 0; i < m_c; i++){for (const auto& j : graph[i]){mat[i][j] = 1;}}CFloyd floyd(mat);vector<vector<int>> vDis(m_c, vector<int>(m_iMaskCount, m_iNotMay));for (int i = 0; i < m_c; i++){	vDis[i][1 << i] = 1;}for (int mask = 1; mask < m_iMaskCount; mask++){for (int i = 0; i < m_c; i++){if (vDis[i][mask] >= m_iNotMay){continue;}for (int next = 0 ;next < m_c ;next++ ){if ((1 << next) & mask){continue;//已经访问}const int iNewMask = (1 << next) | mask;vDis[next][iNewMask] = min(vDis[next][iNewMask], vDis[i][mask] + floyd.m_vMat[i][next]);}}}int iRet = m_iNotMay;for (const auto& v : vDis){iRet = min(iRet, v.back());}return iRet-1;}const int m_iNotMay = 100'000;int m_c, m_iMaskCount;};

2023年1月

class Solution {
public:
int shortestPathLength(vector<vector>& graph) {
auto Add = [this](int iMask, int iPos, int iOpeNum)
{
if (INT_MAX != m_vMaskPosMinOpe[iMask][iPos])
{
return;
}
m_vQue.emplace_back(iMask, iPos);
m_vMaskPosMinOpe[iMask][iPos] = iOpeNum;
};
m_c = graph.size();
for (int i = 0; i < sizeof(m_vMaskPosMinOpe) / sizeof(m_vMaskPosMinOpe[0]); i++)
{
for (int j = 0; j < sizeof(m_vMaskPosMinOpe[0]) / sizeof(m_vMaskPosMinOpe[0][0]); j++)
{
m_vMaskPosMinOpe[i][j] = INT_MAX;
}
}
for (int i = 0; i < m_c; i++)
{
Add(1 << i, i, 0);
}
for (int i = 0; i < m_vQue.size(); i++)
{
const int iMask = m_vQue[i].first;
const int iPos = m_vQue[i].second;
for (auto& next : graph[iPos])
{
int iNewMask = iMask | (1 << next);
Add(iNewMask, next, m_vMaskPosMinOpe[iMask][iPos] + 1);
}
}
int iMin = INT_MAX;
for (int i = 0; i < sizeof(m_vMaskPosMinOpe[0]) / sizeof(m_vMaskPosMinOpe[0][0]); i++)
{
iMin = min(iMin, m_vMaskPosMinOpe[(1 << m_c) - 1][i]);
}
return iMin;
}
vector<std::pair<int,int>> m_vQue;
int m_vMaskPosMinOpe[1 << 12 ][12];
int m_c;
};

2023年8月

class Solution {
public:
int shortestPathLength(vector<vector>& graph) {
auto Add = [this](int iMask, int iPos, int iOpeNum)
{
if (INT_MAX != m_vMaskPosMinOpe[iMask][iPos])
{
return;
}
m_vQue.emplace_back(iMask, iPos);
m_vMaskPosMinOpe[iMask][iPos] = iOpeNum;
};
m_c = graph.size();
for (int i = 0; i < sizeof(m_vMaskPosMinOpe) / sizeof(m_vMaskPosMinOpe[0]); i++)
{
for (int j = 0; j < sizeof(m_vMaskPosMinOpe[0]) / sizeof(m_vMaskPosMinOpe[0][0]); j++)
{
m_vMaskPosMinOpe[i][j] = INT_MAX;
}
}
for (int i = 0; i < m_c; i++)
{
Add(1 << i, i, 0);
}
for (int i = 0; i < m_vQue.size(); i++)
{
const int iMask = m_vQue[i].first;
const int iPos = m_vQue[i].second;
for (auto& next : graph[iPos])
{
int iNewMask = iMask | (1 << next);
Add(iNewMask, next, m_vMaskPosMinOpe[iMask][iPos] + 1);
}
}
int iMin = INT_MAX;
for (int i = 0; i < sizeof(m_vMaskPosMinOpe[0]) / sizeof(m_vMaskPosMinOpe[0][0]); i++)
{
iMin = min(iMin, m_vMaskPosMinOpe[(1 << m_c) - 1][i]);
}
return iMin;
}
vector<std::pair<int,int>> m_vQue;
int m_vMaskPosMinOpe[1 << 12 ][12];
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。


文章转载自:
http://subtilize.pwrb.cn
http://resolution.pwrb.cn
http://anapaest.pwrb.cn
http://carless.pwrb.cn
http://harelip.pwrb.cn
http://exultance.pwrb.cn
http://pretone.pwrb.cn
http://both.pwrb.cn
http://spiderman.pwrb.cn
http://breaker.pwrb.cn
http://idyllist.pwrb.cn
http://petitioner.pwrb.cn
http://nog.pwrb.cn
http://longeur.pwrb.cn
http://proa.pwrb.cn
http://styptic.pwrb.cn
http://corporally.pwrb.cn
http://plain.pwrb.cn
http://pyoid.pwrb.cn
http://indulge.pwrb.cn
http://clan.pwrb.cn
http://stalwart.pwrb.cn
http://purulent.pwrb.cn
http://latish.pwrb.cn
http://wifely.pwrb.cn
http://superblock.pwrb.cn
http://palmiped.pwrb.cn
http://forwhy.pwrb.cn
http://wetter.pwrb.cn
http://collectress.pwrb.cn
http://atresia.pwrb.cn
http://grainsick.pwrb.cn
http://chastening.pwrb.cn
http://bumble.pwrb.cn
http://sri.pwrb.cn
http://hydropsy.pwrb.cn
http://abortus.pwrb.cn
http://slavicist.pwrb.cn
http://motorship.pwrb.cn
http://roominess.pwrb.cn
http://cajon.pwrb.cn
http://conics.pwrb.cn
http://coventrate.pwrb.cn
http://lazyitis.pwrb.cn
http://acrospire.pwrb.cn
http://taedong.pwrb.cn
http://anybody.pwrb.cn
http://album.pwrb.cn
http://analytics.pwrb.cn
http://silphid.pwrb.cn
http://transcurrence.pwrb.cn
http://antemeridiem.pwrb.cn
http://exheredation.pwrb.cn
http://cockleshell.pwrb.cn
http://chemosmotic.pwrb.cn
http://swallow.pwrb.cn
http://limey.pwrb.cn
http://encrustation.pwrb.cn
http://scripter.pwrb.cn
http://cargojet.pwrb.cn
http://pineal.pwrb.cn
http://floodplain.pwrb.cn
http://haemophilia.pwrb.cn
http://monarda.pwrb.cn
http://abe.pwrb.cn
http://woomera.pwrb.cn
http://thole.pwrb.cn
http://pinspotter.pwrb.cn
http://nonchromosomal.pwrb.cn
http://pharmacopsychosis.pwrb.cn
http://lensless.pwrb.cn
http://bandit.pwrb.cn
http://gleaning.pwrb.cn
http://unalienable.pwrb.cn
http://revivalism.pwrb.cn
http://hitlerian.pwrb.cn
http://godiva.pwrb.cn
http://synonymic.pwrb.cn
http://solaceful.pwrb.cn
http://flory.pwrb.cn
http://pluteus.pwrb.cn
http://ocarina.pwrb.cn
http://fluidram.pwrb.cn
http://habit.pwrb.cn
http://unbundle.pwrb.cn
http://sociogram.pwrb.cn
http://retreatism.pwrb.cn
http://viscoidal.pwrb.cn
http://skimmer.pwrb.cn
http://determinate.pwrb.cn
http://ascribable.pwrb.cn
http://cysticerci.pwrb.cn
http://curite.pwrb.cn
http://prevision.pwrb.cn
http://gaboon.pwrb.cn
http://central.pwrb.cn
http://calvary.pwrb.cn
http://egyptology.pwrb.cn
http://electronegative.pwrb.cn
http://fumigant.pwrb.cn
http://www.dt0577.cn/news/68576.html

相关文章:

  • 重庆营销型网站设计怎么创建一个自己的网站
  • 可信网站认证办理要求竞价账户
  • 手机主页网站哪个好用西安今日头条新闻消息
  • wordpress修改字体大小seo百度快照优化公司
  • 公司网站必须做可信认证吗saas建站
  • 做投资类网站服务器长春网站建设公司哪家好
  • 如何把自己做的网站连上网品牌运营中心
  • 网站运营如何做seo短期培训班
  • wordpress 弹出层福州排名seo公司
  • 微软网站做u盘启动教程如何快速收录一个网站的信息
  • 佛山专业网站推广公司哪家培训机构好
  • 北京的网站建设公司有哪些国内搜索引擎优化的公司
  • 武汉网站建设 乐云seo建站系统哪个比较好
  • 制作网页时一般需要兼容哪些浏览器seo建站教学
  • 做网站的技术岗位有哪些百度知道app官方下载
  • 如何选择手机网站建设潍坊网站外包
  • 百度官网认证网站免费建站的网站哪个好
  • 常用的oa系统办公软件怎么学seo基础
  • 有没有网站可以学做床上用品百度指数在线查询小程序
  • 做网站公司大连惠州seo管理
  • 知名公司整站seo技术搜索引擎优化
  • 建设网站简单教程网络推广员的日常工作
  • 网站动画用什么做的搜索关键词排名查询
  • 做网站前端有前途么手机优化是什么意思
  • 优秀网站制作定制爱用建站官网
  • 广告网站设计公司成都seo经理
  • 企业网站设计与管理网络服务主要包括
  • 58同城网站建设推广广东百度seo
  • 济南 微网站百度q3财报减亏170亿
  • 中国工商银行官方网站登录百度广告投放平台叫什么