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

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

思想:

①以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;
     
}
相关推荐
风筝在晴天搁浅3 小时前
代码随想录 718.最长重复子数组
算法
kyle~3 小时前
算法---回溯算法
算法
star _chen3 小时前
C++实现完美洗牌算法
开发语言·c++·算法
hzxxxxxxx3 小时前
1234567
算法
Sylvia-girl4 小时前
数据结构之复杂度
数据结构·算法
CQ_YM4 小时前
数据结构之队列
c语言·数据结构·算法·
VekiSon4 小时前
数据结构与算法——树和哈希表
数据结构·算法
xu_yule5 小时前
数据结构与算法(1)(第一章复杂度知识点)(大O渐进表示法)
数据结构
大江东去浪淘尽千古风流人物6 小时前
【DSP】向量化操作的误差来源分析及其经典解决方案
linux·运维·人工智能·算法·vr·dsp开发·mr
fish_xk6 小时前
数据结构之排序
数据结构