某种带权有向无环图(graph)的所有路径的求法
// 讨论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)的所有路径的求法的更多相关文章
- 图->有向无环图->求关键路径
文字描述 与AOV-网相对应的是AOE-网(Activity on Edge)即边表示活动的网.AOE-网是一个带权的有向无环图.其中,顶点表示事件Event,弧表示活动,权表示活动持续的时间.通常, ...
- javascript实现有向无环图中任意两点最短路径的dijistra算法
有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://w ...
- 算法精解:DAG有向无环图
DAG是公认的下一代区块链的标志.本文从算法基础去研究分析DAG算法,以及它是如何运用到区块链中,解决了当前区块链的哪些问题. 关键字:DAG,有向无环图,算法,背包,深度优先搜索,栈,BlockCh ...
- [转帖]MerkleDAG全面解析 一文读懂什么是默克尔有向无环图
MerkleDAG全面解析 一文读懂什么是默克尔有向无环图 2018-08-16 15:58区块链/技术 MerkleDAG作为IPFS的核心数据结构,它融合了Merkle Tree和DAG的优点,今 ...
- HOJ 13845 Atomic Computer有向无环图的动态规划
考虑任意一个数字,任何一个都会有奇怪的..性质,就是一个可以保证不重复的方案——直接简单粗暴的最高位加数字..于是,如同上面的那个题:+1.-1.0 但是考虑到65536KB的标准内存限制,会得出一个 ...
- UVA_1025 a Spy in the Metro 有向无环图的动态规划问题
应当认为,有向无环图上的动态规划问题是动态规划的基本模型之一,对于某个模型,如果可以转换为某一有向无环图的最长.最短路径问题,则可以套用动态规划若干方法解决. 原题参见刘汝佳紫薯267页. 在这个题目 ...
- 【学习笔记】有向无环图上的DP
手动博客搬家: 本文发表于20180716 10:49:04, 原地址https://blog.csdn.net/suncongbo/article/details/81061378 首先,感谢以下几 ...
- [转帖]算法精解:DAG有向无环图
算法精解:DAG有向无环图 https://www.cnblogs.com/Evsward/p/dag.html DAG是公认的下一代区块链的标志.本文从算法基础去研究分析DAG算法,以及它是如何运用 ...
- DAG(有向无环图)技术
什么是DAG? DAG的全称为"Directed Acyclic Graph",中文意思为:有向无环图,它由有限个顶点和"有向边"组成,从任意顶点出发,经过若干 ...
随机推荐
- 若a与m互质,则a不影响m的完全剩余组
[若a与m互质,则a不影响m的完全剩余组] 设t通过m的完全剩余组,若at不通过m的完全剩余组, 则会有at1=at2(mod m),即a(t1-t2)|m. 因为(a,m)=1,所以(t1-t2)| ...
- OGNL入门
------------------siwuxie095 OGNL 入门 1.OGNL 支持对象方法调用,即 objName.methodName() 如:使用 OGNL 表达式 + Struts2 ...
- set 续3
-------siwuxie095 set 技巧高级篇: 1.利用 set /a 进行赋值 在开启变量延迟情况下,要判断数组 S!n! 的值的情况, 不 ...
- 二叉树垂直遍历 · Binary Tree Vertical Order Traversal
[抄题]: 给定二叉树,返回其节点值的垂直遍历顺序. (即逐列从上到下).如果两个节点在同一行和同一列中,则顺序应 从左到右. 给定一个二叉树 {3,9,20,#,#,15,7} 3 /\ / \ 9 ...
- wcf 调试
1>在开发环境中调试,我们先在WCF服务上将服务Serivce1.svc设置为启动页面 然后在WCF上Debug中启动新实例 服务就启动起来了 2>wcf发布以后调试,只需在Visual ...
- 关于eclipse创建java项目时产生的.settings文件:
在用eclipse创建一个java项目,在项目目录下面往往会发现.settings文件夹并包含一个org.eclipse.core.resources.prefs文件条目. 这个条目是配置项目的编码方 ...
- error:while loading shared libraries: libevent-2.1.so.6: cannot open shared object file: No such file or directory
执行 memcached 启动命令时,报错,提示:error while loading shared libraries: libevent-2.1.so.6: cannot open shared ...
- 使用c语言实现在linux下的openssl客户端和服务器端编程
使用c语言实现在linux下的openssl客户端和服务器端编程 摘自:https://www.cnblogs.com/etangyushan/p/3679457.html 前几天组长让我实现一个使用 ...
- HDU 3157 Crazy Circuits (有源汇上下界最小流)
题意:一个电路板,上面有N个接线柱(标号1~N) 还有两个电源接线柱 + - 然后是 给出M个部件正负极的接线柱和最小电流,求一个可以让所有部件正常工作的总电流. 析:这是一个有源汇有上下界的 ...
- UVa 1395 Slim Span (最小生成树)
题意:给定n个结点的图,求最大边的权值减去最小边的权值最小的生成树. 析:这个和最小生成树差不多,从小到大枚举左端点,对于每一个左端点,再枚举右端点,不断更新最小值.挺简单的一个题. #include ...