关键路径(邻接矩阵)

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <queue>
#include <stack>
#include <Windows.h>

using namespace std;

#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20  //顶点最多个数
#define LENGTH 5           //顶点字符长度

//邻接矩阵
typedef struct _Graph
{
    int matrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  //邻接矩阵
    char vexs[MAX_VERTEX_NUM][LENGTH];           //顶点数组
    int vexnum;                                  //顶点个数
    int arcs;                                    //弧的个数
}Graph;

int LocateVex(const Graph & g, char name[LENGTH])
{
    for (int i = 0; i < g.vexnum; i++)
    {
        if (0 == strcmp(g.vexs[i], name))
        {
            return i;
        }
    }
    return -1;
}

//图的建造
void CreateGraph(Graph &g)
{
    ifstream fcin(_T("criticalpath.txt"));
    fcin>>g.vexnum;
    for (int i = 0; i < g.vexnum; i++)
    {
        for (int j = 0; j < g.vexnum; j++)
        {
            g.matrix[i][j] = INFINITY;
        }
    }
    for (int i = 0; i < g.vexnum; i++)
    {
        fcin>>g.vexs[i];
    }
    fcin>>g.arcs;
    char arcHead[LENGTH];
    char arcTail[LENGTH];
    int weight;
    for (int i = 0; i < g.arcs; i++)
    {
        memset(arcHead, 0, LENGTH);
        memset(arcTail, 0, LENGTH);
        fcin>>arcTail>>arcHead>>weight;
        int x = LocateVex(g, arcHead);
        int y = LocateVex(g, arcTail);
        g.matrix[y][x] = weight;
    }
}

//v的第一个邻接点
int FirstAdjVex(const Graph &g, int v)
{
    for (int i = 0; i < g.vexnum; i++)
    {
        if (g.matrix[v][i] != INFINITY)
        {
            return i;
        }
    }
    return -1;
}

//v相对于w的下一个邻接点
int NextAdjVex(const Graph &g, int v, int w)
{
    for (int i = w + 1; i < g.vexnum; i++)
    {
        if (g.matrix[v][i] != INFINITY)
        {
            return i;
        }
    }
    return -1;
}

//邻接矩阵的输出
void PrintAdjVex(const Graph &g)
{
    for (int i = 0; i < g.vexnum; i++)
    {
        for (int j = 0; j < g.vexnum; j++)
        {
            if (g.matrix[i][j] == INFINITY)
            {
                cout<<"*"<<'\t';
            }
            else
            {
                cout<<g.matrix[i][j]<<'\t';
            }
        }
        cout<<endl;
    }
    cout<<endl;
}

//************************************关键路径************************************begin
int ve[MAX_VERTEX_NUM] = {0};
int vl[MAX_VERTEX_NUM] = {INFINITY};
//查找入度为0的顶点
void FindInDegree(Graph g, int indegree[])
{
    for (int i = 0; i < g.vexnum; i++)
    {
        for (int j = 0; j < g.vexnum; j++)
        {
            if (g.matrix[i][j] != INFINITY)
            {
                indegree[j]++;
            }
        }
    }
}

//拓扑排序
bool TopologicalSort(Graph g, stack<int> &s)
{
    int indegree[MAX_VERTEX_NUM] = {0};
    FindInDegree(g, indegree);
    queue<int> q;
    int i = 0;
    for (; i < g.vexnum; i++)
    {
        if (indegree[i] == 0)
        {
            q.push(i);
        }
    }
    int count = 0;
    while (!q.empty())
    {
        i = q.front();
        s.push(i);
        q.pop();
        count++;
        for (int j = 0; j < g.vexnum; j++)
        {
            if (g.matrix[i][j] != INFINITY)
            {
                if (!(--indegree[j]))
                {
                    q.push(j);
                }
                if (ve[i] + g.matrix[i][j] > ve[j])
                {
                    ve[j] = ve[i] + g.matrix[i][j];
                }
            }
        }
    }
    if (count < g.vexnum)
    {
        return false;
    }
    else
    {
        return true;
    }
}

bool CriticalPath(Graph g)
{
    stack<int> s;
    if (!TopologicalSort(g, s))
    {
        return false;
    }
    for (int i = 0; i < g.vexnum; i++)
    {
        vl[i] = INFINITY;
    }
    vl[g.vexnum - 1] = ve[g.vexnum - 1];
    int i = 0;
    while (!s.empty())
    {
        i = s.top();
        s.pop();
        for (int j = 0; j < g.vexnum; j++)
        {
            if (g.matrix[i][j] != INFINITY)
            {
                int tmp = g.matrix[i][j];
                if (vl[j] - g.matrix[i][j] < vl[i])
                {
                    vl[i] = vl[j] - g.matrix[i][j];
                }
            }
        }
    }
    
    for (int i = 0; i < g.vexnum; i++)
    {
        for (int j = 0; j < g.vexnum; j++)
        {
            if (g.matrix[i][j] != INFINITY)
            {
                if (ve[i] == vl[j] - g.matrix[i][j])
                {
                    cout<<g.vexs[i]<<"  "<<g.vexs[j]<<"  "<< g.matrix[i][j]<<endl;
                }
            }
        
        }
        
    }
    cout<<"最长路径需要"<<vl[g.vexnum - 1]<<""<<endl;
    return true;
}

//************************************关键路径************************************end

//辅助函数,设置控制台的颜色
void SetConsoleTextColor(WORD dwColor)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    if (INVALID_HANDLE_VALUE == handle)
    {
        return;
    }
    SetConsoleTextAttribute(handle, dwColor);
}

int _tmain(int argc, _TCHAR* argv[])
{
    Graph graph;
    CreateGraph(graph);
    SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout<<"************************邻接矩阵**************************"<<endl;
    PrintAdjVex(graph);
    SetConsoleTextColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    cout<<"************************关键路径**************************"<<endl<<endl;
    CriticalPath(graph);
    cout<<endl<<endl;

    return 0;
}

运行的界面如图所示:

构造图用到的criticalpath.txt为:

9
V1 V2 V3 V4 V5 V6 V7 V8 V9
11
V1 V2 6
V1 V3 4
V1 V4 5
V2 V5 1
V3 V5 1
V4 V6 2
V5 V7 9
V5 V8 7
V6 V8 4
V7 V9 3
V8 V9 4
原文地址:https://www.cnblogs.com/venow/p/2643701.html