// 讨论QQ群:135202158

最近做某个东西,最后用图实现了,这里总结一下算法。

假设有以下带权有向无环图(连通或非连通,我这里用的是非连通的):

每个节点(node)可能与其他节点有向地相连,相邻节点的边(edge)有权值(weight)属性。从一个节点到任意一个节点的连的集合称为路径(path),且路径的权为各边权的最小值。

现在的问题就是求所有可能的路径,并算出各路径的权。

以下是简单的C++代码实现,我是用遍历边来实现的,节点和边是两个数据结构:

 #include <iostream>
#include <vector>
#include <list> using namespace std; // 节点
struct node
{
char val; node(char c) : val(c) {}
}; // 边
struct edge
{
// a->b,w为权
node a;
node b;
int w; edge(node& _a, node& _b, int _w) : a(_a), b(_b), w(_w) {}
}; // 遍历各边时所有的记录
struct record
{
list<node> path; // 路径上的节点列表
list<int> ws; // 当前的最小权列表
}; // 生成上图所示带权有向无环图
void gen_samples(vector<node>& nodes, vector<edge>& edges); // 递归遍历
void travel_path(vector<edge>& edges, edge& x, record& r)
{
size_t i;
for(i=; i<edges.size(); ++i)
{
edge e = edges[i];
// 判断是否连通
if(x.b.val == edges[i].a.val)
{
r.path.push_back(edges[i].b);
int w = min(x.w, edges[i].w);
r.ws.push_back(w);
travel_path(edges, edges[i], r);
}
} // 不与任何节点有向连通,输出路径,并回溯至上个节点
if(i == edges.size())
{
for(list<node>::iterator it = r.path.begin();
it != r.path.end(); ++it)
cout << it->val << " ";
cout << ", " << r.ws.back() << endl; r.path.pop_back();
r.ws.pop_back();
}
} int main()
{
vector<node> nodes;
vector<edge> edges; gen_samples(nodes, edges); for(size_t i=; i<edges.size(); ++i)
{
record r;
r.path.push_back(edges[i].a);
r.path.push_back(edges[i].b);
r.ws.push_back(edges[i].w); travel_path(edges, edges[i], r);
} system("PAUSE");
return ;
} void gen_samples(vector<node>& nodes, vector<edge>& edges)
{
node a('A'); nodes.push_back(a);
node b('B'); nodes.push_back(b);
node c('C'); nodes.push_back(c);
node d('D'); nodes.push_back(d);
node e('E'); nodes.push_back(e);
node f('F'); nodes.push_back(f);
node g('G'); nodes.push_back(g);
node h('H'); nodes.push_back(h);
node i('I'); nodes.push_back(i);
node j('J'); nodes.push_back(j);
node k('K'); nodes.push_back(k); edge e1(a, c, ); edges.push_back(e1);
edge e2(b, d, ); edges.push_back(e2);
edge e3(b, e, ); edges.push_back(e3);
edge e4(c, f, ); edges.push_back(e4);
edge e5(c, h, ); edges.push_back(e5);
edge e6(e, h, ); edges.push_back(e6);
edge e7(g, i, ); edges.push_back(e7);
edge e8(g, j, ); edges.push_back(e8);
edge e9(h, k, ); edges.push_back(e9);
}

执行结果为(逗号前面是沿路径的各节点,后面的数字是路径的权):

A C F , 4
A C H K , 1
A C H , 1
A C , 5
B D , 2
B E H K , 3
B E H , 5
B E , 7
C F , 4
C H K , 1
C H , 1
E H K , 3
E H , 5
G I , 2
G J , 8
H K , 3

出来的结果是所有可能的路径,如果要找包含某节点的最长路径的话,这个是有冗余的,需要去一下。

某种带权有向无环图(graph)的所有路径的求法的更多相关文章

  1. 图->有向无环图->求关键路径

    文字描述 与AOV-网相对应的是AOE-网(Activity on Edge)即边表示活动的网.AOE-网是一个带权的有向无环图.其中,顶点表示事件Event,弧表示活动,权表示活动持续的时间.通常, ...

  2. javascript实现有向无环图中任意两点最短路径的dijistra算法

    有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://w ...

  3. 算法精解:DAG有向无环图

    DAG是公认的下一代区块链的标志.本文从算法基础去研究分析DAG算法,以及它是如何运用到区块链中,解决了当前区块链的哪些问题. 关键字:DAG,有向无环图,算法,背包,深度优先搜索,栈,BlockCh ...

  4. [转帖]MerkleDAG全面解析 一文读懂什么是默克尔有向无环图

    MerkleDAG全面解析 一文读懂什么是默克尔有向无环图 2018-08-16 15:58区块链/技术 MerkleDAG作为IPFS的核心数据结构,它融合了Merkle Tree和DAG的优点,今 ...

  5. HOJ 13845 Atomic Computer有向无环图的动态规划

    考虑任意一个数字,任何一个都会有奇怪的..性质,就是一个可以保证不重复的方案——直接简单粗暴的最高位加数字..于是,如同上面的那个题:+1.-1.0 但是考虑到65536KB的标准内存限制,会得出一个 ...

  6. UVA_1025 a Spy in the Metro 有向无环图的动态规划问题

    应当认为,有向无环图上的动态规划问题是动态规划的基本模型之一,对于某个模型,如果可以转换为某一有向无环图的最长.最短路径问题,则可以套用动态规划若干方法解决. 原题参见刘汝佳紫薯267页. 在这个题目 ...

  7. 【学习笔记】有向无环图上的DP

    手动博客搬家: 本文发表于20180716 10:49:04, 原地址https://blog.csdn.net/suncongbo/article/details/81061378 首先,感谢以下几 ...

  8. [转帖]算法精解:DAG有向无环图

    算法精解:DAG有向无环图 https://www.cnblogs.com/Evsward/p/dag.html DAG是公认的下一代区块链的标志.本文从算法基础去研究分析DAG算法,以及它是如何运用 ...

  9. DAG(有向无环图)技术

    什么是DAG? DAG的全称为"Directed Acyclic Graph",中文意思为:有向无环图,它由有限个顶点和"有向边"组成,从任意顶点出发,经过若干 ...

随机推荐

  1. Work-Stealing in .NET 4.0

    [Work-Stealing in .NET 4.0] 1.线程按LIFO取Task,因为最后一个Task很可能还在Cache中,提高命中率. 2.Stealer从FIFO取Task,最先加入的Tas ...

  2. This usually happens because your environment has changed since running `npm install`

    此时运行按照提示执行  npm rebuild node-sass  命令,(如若不行,则先运行npm install node-sass命令执行) 然后再运行 node命令,启动服务.

  3. VMware Workstation 虚拟机的服务启动项

  4. 【hdu4347】The Closest M Points 【KD树模板】

    题意 一个k维空间,给出n个点的坐标,给出t个询问,每个询问给出一个点的坐标和一个m.对于每个询问找出跟这个点最接近的m个点 分析 kd树的模板题. #include <cstdio> # ...

  5. 28. Implement strStr() (String)

    Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...

  6. 编译参数中-pthread以及-lpthread的区别

    一般情况下,我们在链接一个(文件名为libxxx.so或libxxx.a等的)库时,会使用-lxxx的方式:在Linux中要用到多线程时,需要链接pthread库,按照惯例,我们应该使用-lpthre ...

  7. 38-解决Fiddler查看Post参数中文乱码的问题

    转载自:https://blog.csdn.net/JusterDu/article/details/50888617 解决Fiddler查看Post参数中文乱码的问题 2016年03月14日 18: ...

  8. TF Boys (TensorFlow Boys ) 养成记(六): CIFAR10 Train 和 TensorBoard 简介

    圣诞节玩的有点嗨,差点忘记更新.祝大家昨天圣诞节快乐,再过几天元旦节快乐. 来继续学习,在/home/your_name/TensorFlow/cifar10/ 下新建文件夹cifar10_train ...

  9. BUG记忆

      保留两位小数 <fmt:formatNumber value="${list.avgAssessment}" pattern="#.00#"/> ...

  10. Metasploit学习指南—基础篇

    Metasploit是一款强大的渗透测试平台,其中包括了很多渗透测试利器,本文简单介绍一下Metasploit的配置和基础的使用方法,主要包括以下几个方面: Metasploit的核心 基础的配置 M ...