【源代码】C++数据结构算法(十一)用邻接表实现图与关键路径

日常说明:首先博主也是菜鸟一枚,有错误欢迎大家指正。另外本博客所有的代码博主编写后均调试
通过。重要提醒!!!!博主使用的是VS2017,如果有低版本的小伙伴
最好新建空项目将此代码复制上去。
更多算法请关注我的算法专栏https://blog.csdn.net/column/details/20417.html
学过的同学都知道,求得关键路径,要先看拓扑排序能否进行下去,如果一个工程连进行下去都满足不了,更不会有竣工了,关键路径也无从谈起,因此关键路径的算法是建立在拓扑排序的基础上的,可以参照《算法十》中的具体代码。但有一点小小的修改就是在拓扑排序中比较好实现最早开始时间的求解,所以就添加了两行代码。
运行截图:
这里写图片描述

MainPath.h

#pragma once
/**********************************
* algorithms.h : 拓扑排序与关键路径 *
* author : shilei                 *
* created : 2018.4.26           *
***********************************/
#define Max 100
#include <iostream>
#include <cstdlib>
#include<stack>
#include<stdexcept>
typedef int indegree[Max];
using namespace std;

class ArcNode
{
public:
    int Vnum;
    int weight;
    ArcNode *arc_next;
    ArcNode()
    {
        this->arc_next = NULL;
    }
    ArcNode(int Vnum, ArcNode*arc_next = NULL)
    {
        this->arc_next = arc_next;
        this->Vnum = Vnum;
        this->weight = weight;
    }
};

typedef struct VNode
{
    char data;
    ArcNode *firstedge;
}VNode, AdjList[Max];


class ALGraph
{
public:
    ALGraph(indegree indeg);
    int TopologicalSort(ALGraph &graph, indegree indegree);
    void MainPath(ALGraph&graph,indegree indegree);
    //private:
    int edge_num;
    int vexs_num;
    AdjList AdjList[Max];
    int ve[Max] = { 0 };
    int vl[Max];
    bool visited[Max] ;
    stack<int>stack2;
};


ALGraph::ALGraph(indegree indeg)
{

    this->vexs_num = 0;
    this->edge_num = 0;
    cout << "请输入顶点数和边数:";
    cin >> this->vexs_num >> this->edge_num;
    ArcNode *p, *q;
    cout << endl;
    cout << "请输入各顶点:";
    for (int i = 0; i < this->vexs_num; i++)
    {
        indeg[i] = 0;
    }
    for (int i = 0; i < this->vexs_num; i++)
    {
        cin >> this->AdjList[i]->data;
        this->AdjList[i]->firstedge = NULL;
    }
    cout << "请输入箭尾箭头顶点坐标以及相应的权值:" << endl;
    for (int i = 0; i < this->edge_num; i++)
    {
        int j, k, w;
        p = (ArcNode*)malloc(sizeof(ArcNode));
        cin >> j >> k >> w;
        ++indeg[k];
        p->Vnum = k;
        p->weight = w;
        p->arc_next = this->AdjList[j]->firstedge;
        this->AdjList[j]->firstedge = p;
    }

    cout << "顶点   出度表" << endl;
    for (int i = 0; i < this->vexs_num; i++)
    {
        q = (ArcNode*)malloc(sizeof(ArcNode));
        q = this->AdjList[i]->firstedge;
        cout << this->AdjList[i]->data << "       ";
        while (q != NULL)
        {
            int k;
            k = q->Vnum;
            cout << AdjList[k]->data << "   ";
            q = q->arc_next;
        }
        cout << endl;
    }

}

int ALGraph::TopologicalSort(ALGraph &graph, indegree indegree)
{
    //若G无回路,则输出拓扑排序序列并返回1,若有回路返回0。
    ArcNode *q;
    int i, k;
    int gettop;
    stack<int>stack;
    int top = 0;
    for (i = 0; i < graph.vexs_num; i++)
    {
        if (0 == indegree[i])        //将入度为0的顶点入栈
        {
            stack.push(i);
        }
    }
    int count = 0;
    while (!stack.empty())
    {
        gettop = stack.top();
        stack2.push(gettop);
        stack.pop();
        ++count;
        if (count<graph.vexs_num)
        {
            cout << graph.AdjList[gettop]->data << "-->"; //输出i号顶点,并计数
        }
        else
        {
            cout << graph.AdjList[gettop]->data;
        }
        for (q = graph.AdjList[gettop]->firstedge; q; q = q->arc_next)
        {
            k = q->Vnum;
            if (!(--indegree[k]))        //将i号顶点的邻接点的入度减1,如果减1后为0,则入栈
                stack.push(k);
            if (ve[gettop] + q->weight >ve[k])
            {
                ve[k] = ve[gettop] + q->weight;
            }
        }//for
    }//while
    cout << endl;
    if (count <= graph.vexs_num)  return 1;
    return 0;
}

void ALGraph::MainPath(ALGraph&graph,indegree indegree)
{
    ArcNode *q;
    int k, et, lt;
    int gettop;
    /*if (TopologicalSort(graph,indegree) != 0)  return;*/
    for (int i = 0; i < graph.vexs_num; i++)
    {
        visited[i] = false;
        vl[i] = ve[graph.vexs_num - 1];
    }
    while (!stack2.empty())
    {
        gettop = stack2.top();
        stack2.pop();
        for (q = graph.AdjList[gettop]->firstedge; q; q = q->arc_next)
        {
            k = q->Vnum;
            if (vl[k] - q->weight < vl[gettop])
            {
                vl[gettop] = vl[k] - q->weight;
            }
        }//for
    }//while
    visited[0] = true;
    cout << graph.AdjList[0]->data << "-->";
    for (int i = 0; i <graph.vexs_num; i++)
    {
        for (q = graph.AdjList[i]->firstedge; q; q = q->arc_next)
        {
            k = q->Vnum;
            et = ve[k];
            lt = vl[k];
            if (et == lt&&!visited[k])
            {
                if (k<graph.vexs_num-1)
                {
                    cout << graph.AdjList[k]->data << "-->";
                }
                else
                {
                    cout << graph.AdjList[k]->data;
                }
            }//if
            visited[k] = true;
        }//for
    }//for
     /*cout<<graph.AdjList[]*/
    cout << endl;
}

MainPath.cpp

/**********************************
* algorithms.h : 拓扑排序与关键路径 *
* author : shilei                 *
* created : 2018.4.26           *
***********************************/
#include"MainPath.h"
int main()
{
    indegree inde;
    ALGraph graph(inde);
    cout << endl;
    cout << "拓扑排序结果为:" << endl;
    graph.TopologicalSort(graph,inde);
    cout << "关键路径:" << endl;
    graph.MainPath(graph,inde);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/handoking/article/details/80158971