社区
C语言
帖子详情
在不包含循环的有向图中,如何求得两个指定点间的最长路径?
Zark
2003-06-10 12:29:04
在不包含循环的有向图中,如何求得两个指定点间的最长路径? 请或给出伪码,或是C/C++/JAVA代码.既使是大致思路也可以.
预致谢意!
...全文
484
15
打赏
收藏
在不包含循环的有向图中,如何求得两个指定点间的最长路径?
在不包含循环的有向图中,如何求得两个指定点间的最长路径? 请或给出伪码,或是C/C++/JAVA代码.既使是大致思路也可以. 预致谢意!
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
15 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
Zark
2003-06-12
打赏
举报
回复
非常感谢,未能及时回话是因为昨天太忙,然后又要读你的代码,又要研究另一种算法,所以回复迟了.关于你的修改,我再看看,我在运行运程中没有遇到你所说的问题.我想可能是因为我的问题实际上不是任两点的路径,而是在图中只有一个入度为零的顶点和一个出度为零的顶点,我实际是在求这个两点的路径.我在考虑"关键路径"法,好像用拓扑有序这种方法也能解决,不过好像也是O(n^2).
孩皮妞野
2003-06-12
打赏
举报
回复
Zark, 怎么一直没回话,这里有个小bug, 可是我用完了3次,不能再发贴,把我急得。
unsigned max_path_length(unsigned i, unsigned j)
{
if(i==j) return 0; // 递归退出条件
if( max_paths[i][j] != unknown)
return max_paths[i][j]; //已经计算,直接取用计算结果
unsigned max_path = nopath;
unsigned next_vert; // 下一个节点
for(unsigned k=0; k<max_paths.size(); ++k){
if( adj_matrix[i][k]==1 ){ // k是i的后继
unsigned len = max_path_length(k,j);
// 这里做了局部修改,否则可能出现错误
// 当max_path不为nopath而len为nopath时会出现不合理的赋值动作。
if( len!=nopath && (max_path==nopath || max_path<len ) )
max_path = len, next_vert=k;
}
}
if(max_path != nopath)
++max_path;
max_paths[i][j]= max_path;
max_path_next_vert[i][j] = next_vert;
return max_path;
}
Zark
2003-06-12
打赏
举报
回复
非常感谢!经验证,结果正确。
孩皮妞野
2003-06-11
打赏
举报
回复
Zark(金陵五月) ( ) ,
是动态规划法,复杂度好像是O(n^2), 我想不会达不到你的精度要求吧。
建议看一下动态规划法的介绍。 如果有时间我会把这个题目写出来。算法出来了编程没有什么难度。
Zark
2003-06-11
打赏
举报
回复
如果我没有理解错的,你的算法实际上是从结点A到结点C进行多次搜索,并把每次搜索的路径都记录下来,比如A->B->C, A->D->B->C,然后再从其中选择最长的一组.
这是我最原始的想法,类似于穷举法.但我仿佛觉得应该还有更好的算法,不必进行穷举.众所周知,如果求A到C的最短路径,那么穷举法是完全可以成功的,但不是最好的,可以通过类似于树的广度搜索的方法,对A查B和D,发觉没有到达C,分别从B和D出度搜索C,结果是B可以到达C,那么这条路一定是最短的,这样不用穷举即可得到最短路径.
不知老兄对此有无高见,敬请赐教.
nKannan
2003-06-11
打赏
举报
回复
图的遍历问题。
使用一个队列,开始只有点A。
将A可以到达的点放入队列,BD。
查下一个点B,将B可以到达的点入队列,现在有DC。
反复查队列,直到为空。
记录其中到达C点所经历的最长路径。
这是实现最简单但是效率差的方法。
孩皮妞野
2003-06-11
打赏
举报
回复
记顶点数为N, 用一个N*N的矩阵来存储从每一顶点到所有其他顶点的最大长度。
这个矩阵可以一次求出来,反复使用,只要基础图没有改变。
如有问题,欢迎讨论。
孩皮妞野
2003-06-11
打赏
举报
回复
这是DP算法,是多项式复杂度吧。
孩皮妞野
2003-06-11
打赏
举报
回复
我刚才理解错了。
把边的权都置为1。
记从S到D的最长路径的长度为MAXsd,
从S可以直接到达的节点集合为{A,B,C,D...}
则MAXsd = 1+ max{ MAXad, MAXbd, MAXcd, MAXdd...}
在求最长路径长度的同时可以求出最长路径。
Zark
2003-06-11
打赏
举报
回复
多谢回复.
1.我的书上没有这种算法,如有可能请告诉我是哪一本书.
2.这个图没有那么复杂,边是没有权的.举例来说,
A----->B----->C
| ^|
---->D---
从A->C,则要找出A->D->B->C,而不是A->B->C.我不知道如何使用ALNG的方法.
孩皮妞野
2003-06-11
打赏
举报
回复
哦,是图,可以用最小代价生成树的算法[prim/kruskal]. 道理如上。
孩皮妞野
2003-06-11
打赏
举报
回复
你是指不包含同一节点两次的最长路径吧?
最长和最短,看你怎么看。比如对边的权取相反数,或者用某个大数减去权得到新权[这样可以保证权仍为正数],这样用新权得到的最短路径,就是原来权意义上的最长路径。
所以dijikstra算法就可以了。
brucegong
2003-06-11
打赏
举报
回复
数据结构上不是有现成的算法吗?
孩皮妞野
2003-06-11
打赏
举报
回复
另一组稍复杂的数据
C:\ type input.txt
0 9
13
0 1 0 1 0 0 0 0 0 0 0 0 0
0 0 1 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1 0 0 1
0 0 0 0 0 0 0 0 0 1 0 0 0
c:\ lpath <input.txt
11
0 3 1 4 2 5 6 8 10 11 12 9
这个结果也是正确的。
该算法的复杂度为O(n^2).
孩皮妞野
2003-06-11
打赏
举报
回复
局部还可以优化。在CB6下运行通过,以你的样本数据测试通过。没做进一步测试。
必须保证输入的矩阵没有回路,否则可能陷入死循环[?]。
// 解Zark最长路径问题的DP算法。
// ALNG 2003-6-11
//
//
//---------------------------------------------------------------------------
// 输入文件的格式
// 源 目标
// 顶点数
// 邻接矩阵
//
// 示例输入文件input.txt, 就是zark给出的示例图
// 0 2
// 4
// 0 1 0 1
// 0 0 1 0
// 0 0 0 0
// 0 1 0 0
//
// 输出
// 路径长度
// 路径
//
// 示例输出
// 3
// 0 3 2
#include <iostream>
#include <vector>
typedef std::vector< std::vector<unsigned> > matrix;
matrix max_paths; // 存储最长路径长度的矩阵
matrix max_path_next_vert; // 用于构造出最长路径
matrix adj_matrix; // 邻接矩阵
// max_paths中用到的特殊值
const unsigned unknown = 0, // 表明两个顶点间的最长路径长度未知
nopath = unsigned(-1); // 表明两个顶点间的最长路径长度未知
// 从标准输入中读入邻接矩阵
//
// input:
// n[in]: count of vertices
//
// remark: this function modifies global variable max_paths and adj_matrix
void read_adj_matrix(unsigned n)
{
// read adjacent matrix from stand input
adj_matrix.resize(n);
for(unsigned i=0; i<n; ++i){
adj_matrix[i].resize(n);
for(unsigned j=0; j<n; ++j){
std::cin>>adj_matrix[i][j];
}
}
// initialize max_paths, set all of its elements to unknown
max_paths.resize(n);
max_path_next_vert.resize(n);
for(unsigned i=0; i<n; ++i){
max_paths[i].resize(n);
max_path_next_vert[i].resize(n);
for(unsigned j=0; j<n; ++j)
max_paths[i][j] = unknown;
}
}
// 取得从i到j的最大路径的长度
//
// 返回 unsigned(-1)表示没有从i到j的路径
// 其它:
unsigned max_path_length(unsigned i, unsigned j)
{
if(i==j) return 0; // 递归退出条件
if( max_paths[i][j] != unknown)
return max_paths[i][j]; //已经计算,直接取用计算结果
unsigned max_path = nopath;
unsigned next_vert; // 下一个节点
for(unsigned k=0; k<max_paths.size(); ++k){
if( adj_matrix[i][k]==1 ){ // k是i的后继
unsigned len = max_path_length(k,j);
if( max_path==nopath || max_path<len )
max_path = len, next_vert=k;
}
}
if(max_path != nopath)
++max_path;
max_paths[i][j]= max_path;
max_path_next_vert[i][j] = next_vert;
return max_path;
}
void longest_path(unsigned i, unsigned j)
{
unsigned len;
if( (len=max_path_length(i,j) ) != nopath){
std::cout<<len<<std::endl<<i;
for(unsigned k=max_path_next_vert[i][j]; k!=j;i=k,k=max_path_next_vert[i][j])
std::cout<<' '<<k;
std::cout<<' '<<j<<std::endl;
}else
std::cout<<"there is no path between "<<i<<" and "<<j<<std::endl;
}
#pragma argsused
int main(int argc, char* argv[])
{
using std::cin;
using std::cout;
using std::endl;
unsigned src, dst, n;
cin>>src>>dst>>n;
read_adj_matrix(n);
longest_path(src,dst);
return 0;
}
//---------------------------------------------------------------------------
有向图
最长
路径
算法_【洛谷日报#16】SPFA算法教学
目录引入1:单源最短路原理&讲解模拟&代码引入2:判正(负)环BFS版SPFADFS版SPFA例题总结后话SPFA算法是一种图论算法,可以看作是Bellman-Ford算法的队列优化。它可以求出单源最短路,也可检测到负环,实现起来也比较容易。但是现在很多题目会卡SPFA,所以要看情况使用。引入1:单源最短路问:求带权
有向图
上一个源点到其他点的最短
路径
距离如果没有非负边权,我们自然可...
寻找
有向图
网络
中
每个节点的最大传播
路径
长度
针对
有向图
G,寻找每个节点的最大传播
路径
长度。 如果一个节点没有邻居节点,则传播
路径
长度为0;
有向图
,可能存在闭环
路径
,会造成在闭环回路
中
进行传播,陷入死
循环
; def get_max_path_list(G): path_len = [] for node in tqdm(list(g.nodes)): for _ in list(g.nodes): g.nodes[_]["state"]=0 g.nodes[node]["state"]=1 k = 0
有向图
的
最长
路径
及是否存在环路结构
问题描述: 有n个长为m+1的字符串,如果某个字符串的最后m个字符与某个字符串的前m个字符匹配,则
两个
字符串可以连接。问这n个字符串最多可以连成一个多长的字符串,如果出现
循环
,则返回错误。 分析: 把每个字符串看成一个图的顶点,
两个
字符串可以连接就形成一条有向边。相当于判断一个
有向图
是否存在环以及求该
有向图
的
最长
路径
。 可用图的深度优先遍历算法来求解,图用邻接表表示。 1. 求解有
ACM 在有向无环图
中
求
最长
路径
http://www.geeksforgeeks.org/find-longest-path-directed-acyclic-graph/给定一个带权有向无环图及源点S,在图
中
找出从S出发到图
中
其它所有顶点的
最长
距离。对于一般的图,求
最长
路径
并不向最短
路径
那样容易,因为
最长
路径
并没有最优子结构的属性。实际上求
最长
路径
属于NP-Hard问题。然而,对于有向无 环图,
最长
路径
问题有线性时间的解。思路
求
有向图
的
最长
路径
题目:有n 个长为m+1 的字符串,如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则
两个
字符串可以联接,问这n 个字符串最多可以连成一个多长的字符串,如果出现
循环
,则返回错误。 这个题目转化为图来做,设每个字符串看做一个顶点,如果(u,v)满足u的后m个字符和v的前m个字符匹配,则连边,权值设置为1即可。 然后针对建好的图,进行拓扑排序,并检查是否有环,如果有环,直接返回fal...
C语言
70,026
社区成员
243,244
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章