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

品牌网站建设1毛尖ip设计

品牌网站建设1毛尖,ip设计,免费咨询的英文,长沙开福区专业制作网站文章目录 前言一、Dijkstra#xff08;迪克斯特拉#xff09;1.方法#xff1a;2.代码实现 二、FloydWarshall#xff08;弗洛伊德#xff09;1.方法2.代码实现 完整源码 前言 最短路径问题#xff1a;从在带权有向图G中的某一顶点出发#xff0c;找出一条通往另一顶点… 文章目录 前言一、Dijkstra迪克斯特拉1.方法2.代码实现 二、FloydWarshall弗洛伊德1.方法2.代码实现 完整源码 前言 最短路径问题从在带权有向图G中的某一顶点出发找出一条通往另一顶点的最短路径最短也就是沿路径各边的权值总和达到最小。 单源最短路径问题给定一个图G ( V E ) G(VE)G(VE)求源结点s ∈ V s∈Vs∈V到图 中每个结点v ∈ V v∈Vv∈V的最短路径 一、Dijkstra迪克斯特拉 1.方法 针对一个带权有向图G将所有结点分为两组S和QS是已经确定最短路径的结点集合在初始时 为空初始时就可以将源节点s放入毕竟源节点到自己的代价是0Q 为其余未确定最短路径 的结点集合每次从Q 中找出一个起点到该结点代价最小的结点u 将u 从Q 中移出并放入S 中对u 的每一个相邻结点v 进行松弛操作。松弛即对每一个相邻结点v 判断源节点s到结点u 的代价与u 到v 的代价之和是否比原来s 到v 的代价更小若代价比原来小则要将s 到v 的代价更新 为s 到u 与u 到v 的代价之和否则维持原样。如此一直循环直至集合Q 为空即所有节点都已经 查找过一遍并确定了最短路径 Dijkstra算法每次都是选择V-S中最小的路径节点来进行更新并加入S中所以该算法使用的是贪心策略。 核心就是从当前选入的顶点当中去找其直接相连的最小的边然后用这个最小边相连的另一个顶点为起点找与其直接相连边中最小的边eg与s直接相连的为ty。最小的边为5即y顶点其为s到y的最短距离然后以y为起点与y直接相连的有txz。最小的边为2即z点y到z最短为2所以s到z最短为7以此类推直到所有点都被当过起点后结束 2.代码实现 void Dijkstra(const V src, vectorW dist, vectorint pPath){//dist存的src到其他点的最短路径// vectorint pPath 记录srci-其他顶点最短路径父顶点数组size_t srci GetVertexIndex(src);size_t n _vertexs.size();dist.resize(n, MAX_W);pPath.resize(n, -1);dist[srci] 0;//自己到自己距离为0pPath[srci] srci;// 已经确定最短路径的顶点集合vectorbool S(n, false);for (size_t j 0; j n; j){int u srci;//u为当前最短路径顶点W min MAX_W;//min为起始点到u的距离for (size_t i 0; i n; i){if (S[i] false dist[i] min){u i;min dist[i];}}//找到与当前起始点直接相连的最短路径的顶点后//将其位置置为true表明已经选入S[u] true;// 松弛算法更新一遍u连接的所有边看是否能更新出更短连接路径for (size_t v 0; v n; v){// 如果srci-u u-k 比 srci-k更短 则进行更新if (S[v] false _matrix[u][v] ! MAX_W dist[u] _matrix[u][v] dist[v]){dist[v] dist[u] _matrix[u][v];pPath[v] u;}}}}//打印路径 void PrintShortPath(const V src, const vectorW dist, const vectorint pPath) {size_t srci GetVertexIndex(src);size_t n _vertexs.size();for (size_t i 0; i n; i) {if (i ! srci) {vectorintpath;//path为src到其他顶点路径size_t parenti i;while (parenti ! srci) {path.push_back(parenti);parenti pPath[parenti];}path.push_back(srci);//需要反转一下因为我们从s-x-v//是从v的父亲为x再推出x的父亲为s才结束的reverse(path.begin(), path.end());for (auto index : path) {cout _vertexs[index] -;}cout 权值和 dist[i] endl;}}}Dijkstra算法存在的问题是不支持图中带负权路径如果带有负权路径则可能会找不到一些路 径的最短路径。 二、FloydWarshall弗洛伊德 多源最短路径Floyd-Warshall算法是解决任意两点间的最短路径的一种算法。 1.方法 Floyd算法考虑的是一条最短路径的中间节点即简单路径p{v1,v2,…,vn}上除v1和vn的任意节 点。 设k是p的一个中间节点那么从i到j的最短路径p就被分成i到k和k到j的两段最短路径p1p2。p1 是从i到k且中间节点属于{12…k-1}取得的一条最短路径。p2是从k到j且中间节点属于{1 2…k-1}取得的一条最短路径。 核心将中间经过的k当成所经过s-…-j中间经过的所有中间顶点集合中的一个把中间的所有顶点看成k。 2.代码实现 void FloydWarshall(vectorvectorW vvDist, vectorvectorint vvpPath){size_t n _vertexs.size();vvDist.resize(n);vvpPath.resize(n);// 初始化权值和路径矩阵for (size_t i 0; i n; i){vvDist[i].resize(n, MAX_W);vvpPath[i].resize(n, -1);}//vvpPath[i][j]表示i-j,j的父亲为i// 直接相连的边更新一下//把目前已知直接相连的边放入vvDist中并更新vvpPath[i][j]for (size_t i 0; i n; i){for (size_t j 0; j n; j){if (_matrix[i][j] ! MAX_W){vvDist[i][j] _matrix[i][j];vvpPath[i][j] i;}if (i j){vvDist[i][j] W();}}}// 最短路径的更新i- {其他顶点} -j//这里要进行k次的原因是因为我们所有结点都有可能//成为src与dst的中间结点所以要考虑所有情况for (size_t k 0; k n; k){for (size_t i 0; i n; i){for (size_t j 0; j n; j){// k 作为的中间点尝试去更新i-j的路径if (vvDist[i][k] ! MAX_W vvDist[k][j] ! MAX_W vvDist[i][k] vvDist[k][j] vvDist[i][j]){vvDist[i][j] vvDist[i][k] vvDist[k][j];vvpPath[i][j] vvpPath[k][j];//因为这里k实际上是中间顶点集合// 找跟j相连的上一个邻接顶点// 如果k-j 直接相连上一个点就kvvpPath[k][j]存就是k// 如果k-j 没有直接相连k-...-x-jvvpPath[k][j]存就是x}}}// 打印权值和路径矩阵观察数据for (size_t i 0; i n; i){for (size_t j 0; j n; j){if (vvDist[i][j] MAX_W){//cout * ;printf(%3c, *);}else{//cout vvDist[i][j] ;printf(%3d, vvDist[i][j]);}}cout endl;}cout endl;for (size_t i 0; i n; i){for (size_t j 0; j n; j){//cout vvParentPath[i][j] ;printf(%3d, vvpPath[i][j]);}cout endl;}cout endl;}}};完整源码 如果对Graph这些代码不太熟悉的小伙伴可以参考我之前写的【数据结构】图的创建邻接矩阵邻接表以及深度广度遍历BFS,DFS namespace matrix {//V为顶点类型W为边权值类型MAX_W为权值最大值也就是无效值//Direction用来判断是不是有向图false为无向图templateclass V,class W,W MAX_WINT_MAX,bool Directionfalseclass Graph {public:Graph() default;Graph(const V* a, size_t n) {_vertexs.reserve(n);for (size_t i 0; i n; i) {_vertexs.push_back(a[i]);_indexMap[a[i]] i;//将顶点存入_vertexs下标映射存进map}_matrix.resize(n);for (size_t i 0; i _matrix.size(); i) {_matrix[i].resize(n, MAX_W);//邻接矩阵默认初始值为无效值}}size_t GetVertexIndex(const V v) {//获得对应顶点在数组中的下标auto it _indexMap.find(v);if (it ! _indexMap.end()) {return it-second;//有这个顶点返回其下标}else {throw(顶点不存在);return -1;}}void _AddEdge(size_t srci, size_t dsti, const W w) {//存入权值_matrix[srci][dsti] w;if (Direction false) {_matrix[dsti][srci] w;//无向图要两个方向都存}}void AddEdge(const V src, const V dst, const W w) {//添加边与顶点的关系。从src到dst方向的关系size_t srci GetVertexIndex(src);size_t dsti GetVertexIndex(dst);//先获取其对应的下标_AddEdge(srci, dsti, w);}void Print() {for (size_t i 0; i _vertexs.size(); i) {cout [ i ] - _vertexs[i] endl;}//打印顶点集cout endl;//打印邻接矩阵for (size_t i 0; i _matrix.size(); i) {cout i ;for (size_t j 0; j _matrix[i].size(); j) {if (_matrix[i][j] MAX_W) {printf(%4c, *);}else {printf(%4d, _matrix[i][j]);}}cout endl;}}void BFS(const V src) {size_t srci GetVertexIndex(src);queueintq;q.push(srci);vectorboolvisited(_vertexs.size(), false);visited[srci] true;//标记这个顶点被访问过了int levelSize 1;while (!q.empty()) {//levelSize为当前层的大小for (size_t i 0; i levelSize; i) {int front q.front();q.pop();cout front : _vertexs[front] ;for (size_t i 0; i _vertexs.size(); i) {if (_matrix[front][i] ! MAX_W visited[i] false) {q.push(i);visited[i] true;//标记这个顶点被访问过了}}}levelSize q.size();//更新当前层的数量cout endl;}cout endl;}void _DFS(size_t srci, vectorbool visited) {cout srci : _vertexs[srci] endl;visited[srci] true;//标记这个顶点被访问过了for (size_t i 0; i _vertexs.size(); i) {if (_matrix[srci][i] ! MAX_W visited[i] false) {_DFS(i, visited);}}}void DFS(const V src) {size_t srci GetVertexIndex(src);vectorboolvisited(_vertexs.size(), false);_DFS(srci, visited);}typedef GraphV, W, MAX_W, false Self;//建立边的类保存边的两个顶点下标和权值struct Edge {size_t _srci;size_t _dsti;W _w;Edge(size_t srci,size_t dsti,W w):_srci(srci),_dsti(dsti),_w(w){}bool operator(const Edge e)const {return _w e._w;//小根堆判断}};W Kruskal(Self minTree){//minTree为最小生成树刚开始什么都没有size_t n _vertexs.size();//初始化最小生成树minTree._vertexs _vertexs;minTree._indexMap _indexMap;minTree._matrix.resize(n);for (size_t i 0; i n; i){minTree._matrix[i].resize(n, MAX_W);}//我们每次选边从全部边中选出最小的保证不构成回路的情况//所以我们可以考虑用小根堆来存入边这样每次方便找最小的priority_queueEdge, vectorEdge, greaterEdge minque;for (size_t i 0; i n; i){for (size_t j 0; j n; j){if (i j _matrix[i][j] ! MAX_W){//将所有有效值边放进堆中minque.push(Edge(i, j, _matrix[i][j]));}}}int size 0;W totalW W();UnionFindSet ufs(n); // 选出n-1条边while (!minque.empty()){//取出最小边Edge min minque.top();minque.pop();if (!ufs.InSet(min._srci, min._dsti))//判断是否成环{//cout _vertexs[min._srci] - _vertexs[min._dsti] :min._w endl;//不成环就将当前边放入最小生成树当中minTree._AddEdge(min._srci, min._dsti, min._w);//并把这两个顶点放入同一个并查集集合当中ufs.Union(min._srci, min._dsti);size;totalW min._w;//权值总和增加}else{//cout 构成环;//cout _vertexs[min._srci] - _vertexs[min._dsti] : min._w endl;}}if (size n - 1)//边数选够说明最小生成树//创建成功{return totalW;}else{return W();}}W Prim(Self minTree, const W src){size_t srci GetVertexIndex(src);size_t n _vertexs.size();minTree._vertexs _vertexs;minTree._indexMap _indexMap;minTree._matrix.resize(n);for (size_t i 0; i n; i){minTree._matrix[i].resize(n, MAX_W);}vectorbool X(n, false);vectorbool Y(n, true);X[srci] true;Y[srci] false;// 从X-Y集合中连接的边里面选出最小的边priority_queueEdge, vectorEdge, greaterEdge minq;// 先把srci连接的边添加到小根堆中for (size_t i 0; i n; i){if (_matrix[srci][i] ! MAX_W){minq.push(Edge(srci, i, _matrix[srci][i]));}}cout Prim开始选边 endl;size_t size 0;//选出边的数量W totalW W();//权值之和while (!minq.empty()){Edge min minq.top();minq.pop();// 最小边的目标点也在X集合则构成环if (X[min._dsti]){//cout 构成环:;//cout _vertexs[min._srci] - _vertexs[min._dsti] : min._w endl;}else{//从Y中选出顶点minTree._AddEdge(min._srci, min._dsti, min._w);//加入最小生成树//cout _vertexs[min._srci] - _vertexs[min._dsti] : min._w endl;X[min._dsti] true;Y[min._dsti] false;size;totalW min._w;if (size n - 1)break;//把新加入顶点相关的边都放入小根堆中for (size_t i 0; i n; i){if (_matrix[min._dsti][i] ! MAX_W Y[i]){minq.push(Edge(min._dsti, i, _matrix[min._dsti][i]));}}}}if (size n - 1){return totalW;}else{return W();}}void PrintShortPath(const V src, const vectorW dist, const vectorint pPath) {size_t srci GetVertexIndex(src);size_t n _vertexs.size();for (size_t i 0; i n; i) {if (i ! srci) {vectorintpath;//path为src到其他顶点路径size_t parenti i;while (parenti ! srci) {path.push_back(parenti);parenti pPath[parenti];}path.push_back(srci);//需要反转一下因为我们从s-x-v//是从v的父亲为x再推出x的父亲为s才结束的reverse(path.begin(), path.end());for (auto index : path) {cout _vertexs[index] -;}cout 权值和 dist[i] endl;}}}void Dijkstra(const V src, vectorW dist, vectorint pPath){//dist存的src到其他点的最短路径// vectorint pPath 记录srci-其他顶点最短路径父顶点数组size_t srci GetVertexIndex(src);size_t n _vertexs.size();dist.resize(n, MAX_W);pPath.resize(n, -1);dist[srci] 0;//自己到自己距离为0pPath[srci] srci;// 已经确定最短路径的顶点集合vectorbool S(n, false);for (size_t j 0; j n; j){int u srci;//u为当前最短路径顶点W min MAX_W;//min为起始点到u的距离for (size_t i 0; i n; i){if (S[i] false dist[i] min){u i;min dist[i];}}//找到与当前起始点直接相连的最短路径的顶点后//将其位置置为true表明已经选入S[u] true;// 松弛算法更新一遍u连接的所有边看是否能更新出更短连接路径for (size_t v 0; v n; v){// 如果srci-u u-k 比 srci-k更短 则进行更新if (S[v] false _matrix[u][v] ! MAX_W dist[u] _matrix[u][v] dist[v]){dist[v] dist[u] _matrix[u][v];pPath[v] u;}}}}void FloydWarshall(vectorvectorW vvDist, vectorvectorint vvpPath){size_t n _vertexs.size();vvDist.resize(n);vvpPath.resize(n);// 初始化权值和路径矩阵for (size_t i 0; i n; i){vvDist[i].resize(n, MAX_W);vvpPath[i].resize(n, -1);}//vvpPath[i][j]表示i-j,j的父亲为i// 直接相连的边更新一下//把目前已知直接相连的边放入vvDist中并更新vvpPath[i][j]for (size_t i 0; i n; i){for (size_t j 0; j n; j){if (_matrix[i][j] ! MAX_W){vvDist[i][j] _matrix[i][j];vvpPath[i][j] i;}if (i j){vvDist[i][j] W();}}}// 最短路径的更新i- {其他顶点} -j//这里要进行k次的原因是因为我们所有结点都有可能//成为src与dst的中间结点所以要考虑所有情况for (size_t k 0; k n; k){for (size_t i 0; i n; i){for (size_t j 0; j n; j){// k 作为的中间点尝试去更新i-j的路径if (vvDist[i][k] ! MAX_W vvDist[k][j] ! MAX_W vvDist[i][k] vvDist[k][j] vvDist[i][j]){vvDist[i][j] vvDist[i][k] vvDist[k][j];vvpPath[i][j] vvpPath[k][j];//因为这里k实际上是中间顶点集合// 找跟j相连的上一个邻接顶点// 如果k-j 直接相连上一个点就kvvpPath[k][j]存就是k// 如果k-j 没有直接相连k-...-x-jvvpPath[k][j]存就是x}}}// 打印权值和路径矩阵观察数据for (size_t i 0; i n; i){for (size_t j 0; j n; j){if (vvDist[i][j] MAX_W){//cout * ;printf(%3c, *);}else{//cout vvDist[i][j] ;printf(%3d, vvDist[i][j]);}}cout endl;}cout endl;for (size_t i 0; i n; i){for (size_t j 0; j n; j){//cout vvParentPath[i][j] ;printf(%3d, vvpPath[i][j]);}cout endl;}cout endl;}}private:vectorV_vertexs;//顶点集合mapV, int_indexMap;//存顶点与数组下标的映射关系vectorvectorW_matrix;//邻接矩阵};}
http://www.zqtcl.cn/news/49648/

相关文章:

  • 湛江网站排名优化汕头网站关键排名
  • 网站建设方案设计ppt针织外贸公司
  • 极速云建站在线简易网页制作网站
  • 做网站会员金字塔系统中国山东建设监理协会官方网站
  • 网站建设玖金手指排名11义乌市评建设职称网站
  • 在线视频网站开发梧州seo排名
  • 百度快速收录方法seo关键词优化
  • 一台ip做两个网站自定义图片制作
  • 深圳外包网站公司建设网站如何赢利
  • WordPress全站跳转网站开发资金规模
  • 悬赏做海报的网站wordpress 页面 分类目录
  • html5网站上线模版个人购买链接
  • 世界上有php应用的网站wordpress主题淘宝客
  • 做外贸没有网站需要注意什么问题wordpress缩略图采集火车头
  • 网站内容建设和管理免费用手机做网站
  • 建站之星 discuz手机网站建站
  • 官方网站的资料做证据wordpress+仿简书模板
  • 安康做企业网站的邢台手机网站制作
  • 百度推广是否做网站wordpress怎么放图片不显示
  • 做推广都有什么网站网站动态海报效果怎么做的
  • 杭州电商网站建设品牌网络推广公司
  • 无锡手机网站制作费用安徽建站网站
  • 福州网站开发si7.cc传奇游戏在线玩网页版
  • 广州网站维护公司常见的网络服务有哪些
  • 中山低价网站建设网页设计培训班学校排名
  • 建外文网站湖南省建设信息网站查询
  • 动态倒计时网站模板怎么做直播室的网站
  • 软件开发建设网站网站建设百度推广
  • 网站运行速度慢html建站
  • 网站开发的重要性深圳平面设计公司排名榜