社区
C语言
帖子详情
在不包含循环的有向图中,如何求得两个指定点间的最长路径?
Zark
2003-06-10 12:29:04
在不包含循环的有向图中,如何求得两个指定点间的最长路径? 请或给出伪码,或是C/C++/JAVA代码.既使是大致思路也可以.
预致谢意!
...全文
433
15
打赏
收藏
在不包含循环的有向图中,如何求得两个指定点间的最长路径?
在不包含循环的有向图中,如何求得两个指定点间的最长路径? 请或给出伪码,或是C/C++/JAVA代码.既使是大致思路也可以. 预致谢意!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用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;
}
//---------------------------------------------------------------------------
iOS开发
中
的神兵利器
【课程概括】
包含
306节超多互动教程,基于新版的Swift和Xcode。手把手讲解大量实用的iOS开发开源类库:BonMot、PKHUD、DZNEmptyDataSet、Alamofire、Moya、Promise、Kingfisher、SnapKit、组件化编程、RxSwift响应式编程、Lottie动画、Hero转场动画、app主题更换、强大的幻灯片、GPUImage图像视频处理、Realm数据库、二维码创建和读取、模拟网络fake数据、自动化压力测试。手把手学习iOS开发
中
的强大的第三方类库,详细讲解Github
中
的热门的iOS开发开源项目。助您快速、优雅地解决iOS开发
中
棘手的业务需求!【课程特点】 1、代码逐行讲解2、语言简洁、精练、瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间3、完美贴心的操作提示,让您的眼睛始终处于操作的焦点位置,不用再满屏找光标4、每个视频都很短小精悍,即方便于您的学习和记忆,也方便日后对功能的检索 【福利来了】获取306节所有课程源码及加入学习群!
有向无环图
中
的
最长
路径
-PART1
有向无环图
中
的
最长
路径
-PART1 给定一个加权有向无环图DAG和一个源点s在它,找到从s
中
最长
的距离在给定图
中
的所有其他顶点 一般图的
最长
路径
问题不像最短
路径
问题那么容易,因为
最长
路径
问题不具有最优子结构属性。事实上,
最长
路径
问题对于一般的图来说是NP-Hard问题。然而,对于有向无环图的
最长
路径
问题,其具有线性时间解。这个想法类似于有向无环图
中
最短
路径
的线性时间解决方案,我们使用拓扑排序。 我们将到所有顶点的距离初始化为负无穷大,到源点的距离初始化为 0,然后我们找到图的拓扑排序。图的拓扑排序表示图
寻找
有向图
网络
中
每个节点的最大传播
路径
长度
针对
有向图
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. 求解有
求
有向图
的
最长
路径
题目:有n 个长为m+1 的字符串,如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则
两个
字符串可以联接,问这n 个字符串最多可以连成一个多长的字符串,如果出现
循环
,则返回错误。 这个题目转化为图来做,设每个字符串看做一个顶点,如果(u,v)满足u的后m个字符和v的前m个字符匹配,则连边,权值设置为1即可。 然后针对建好的图,进行拓扑排序,并检查是否有环,如果有环,直接返回fal...
C语言
69,371
社区成员
243,080
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章