实现用拓扑排序方法求有向无环图中最长路径长度的算法

编写程序,实现用拓扑排序方法求有向无环图中最长路径长度的算法。

思想:

①以maxDist[v]表示以v为结尾的最长路径,G.Edge存储的是图的边的权值,u是v的直接前驱,那么maxDist[v]=max(maxDist[v],maxDist[u]+G.Edge[u][v])表示:maxDist[v]和maxDist[u]+G.Edge[u][v]中最长的一个。

②顶点的计算顺序应该是和拓扑序列的结果一致。

③最长路径一定是从初始入度为0的顶点开始

④maxDist数组中最大值为所求maxPathvalue结果。

代码:

复制代码
typedef struct {                    // 图的定义
    int numV, numEdges;      // 图中实际的顶点数和边数
    char VerticesList[MAXV];        // 顶点表,MAXV为已定义常量
    int Edge[MAXV][MAXV];           // 邻接矩阵
}MGraph;

//获取每个结点的入度 
int *getIndegree(MGraph *G){
    int *indegree = (int*)malloc(sizeof(int)*G.numV);
    
    //初始化每个顶点的入度为0
    for(int i=0;i<G.numV;i++){
        indegree[i]=0;
    } 
    
    //遍历邻接矩阵
    for(int i=0;i<G.numV;i++){
        for(int j=0;j<G.numV;j++){
            if(G.Edge[i][j] != 0){
                indegree[j]++;
            }
        }
    } 
    return indegree
}

//拓扑遍历
bool topsort(MGraph *G){
    //topResult用来保存拓扑序列 
    int *topResult = (int*)malloc(sizeof(int)*G.numV);
    int topResultIndex = 0;
    //计算每个结点的入度 
    int *indegree=getIndegree(G);
    
    //找一个入度为0的顶点
    int stack[MAXSIZE];
    top=-1;
    
    //入度为0的顶点入队
    for(int i=0;i<G.numV;i++){
        if(indegree[i]=0){
            stack[++top]=i;
        }
    } 
    
    //栈不为空时
    while(top != -1){
        //完成拓扑排序的个数+1
        
        
        //出栈
        int v=stack[top--];
        topResult[topResultIndex++]=v;
        
        //由该顶点发出的边到到的顶点,入度均减1
        for(int i=0;i<G.numV;i++){
            if(G.Edge[v][i]==1){
                indegree[i]--;
                //出现新的入度为0的顶点
                if(indegree[i]==0){
                    //入队
                    stack[++top]; 
                } 
            }
        } 
    } 
    free(indegree);
    return topResult;
    
} 

int getMaxPath(MGraph *G){
    int topResult=topsort(G);//进行拓扑排序
    
    //maxDist[v]表示以v为结尾的最长路径 
    int *maxDist=(int*)malloc(sizeof(int)*G.numV);
    memset(maxDist,0,sizeof(int)*G.numV); 
    
    
    int maxPathvalue = -1;//最长路径长度,初始化为-1
    //按照拓扑排序的顺序进行处理
    for(int i=0;i<n;++i){
        int v=topResult[i];
        for(int u=0;u<G.numV;++u){
            if(G.Edge[u][v] != 0){//从u到v有路径 
                maxDist[v]=max(maxDist[v],maxDist[u]+G.Edge[u][v]);
                if(maxDist[v]>maxPathValue){//记录产生的最大值 
                    maxPathvalue = maxDist[v];
                }
            }
        }
    } 
    free(topRuslt);
    free(maxDist);
    
    return maxPathvalue;
     
}
相关推荐
菜择贰6 小时前
B树的性质和查找、插入、删除操作
数据结构·b树
LDR0066 小时前
接口焦虑终结者:LDR6020 芯片如何重新定义 Type-C 拓展坞与多设备互联时代
数据结构·经验分享·智能音箱
房开民7 小时前
可变参数模板
java·开发语言·算法
_深海凉_8 小时前
LeetCode热题100-最小栈
java·数据结构·leetcode
不知名的忻8 小时前
Morris遍历(力扣第99题)
java·算法·leetcode·morris遍历
状元岐8 小时前
C#反射从入门到精通
java·javascript·算法
_深海凉_9 小时前
LeetCode热题100-除了自身以外数组的乘积
数据结构·算法·leetcode
Kk.08029 小时前
项目《基于Linux下的mybash命令解释器》(一)
前端·javascript·算法
xiaotao13110 小时前
01-编程基础与数学基石: Python核心数据结构完全指南
数据结构·人工智能·windows·python
SteveSenna10 小时前
Trossen Arm MuJoCo自定义1:改变目标物体
人工智能·学习·算法·机器人