zoukankan      html  css  js  c++  java
  • 关键路径(邻接矩阵)

    #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
  • 相关阅读:
    (转载)Linux系统中分离线程的使用
    (转载)Vim的几种模式介绍
    (转载)Linux下检查内存泄漏、系统性能的系列工具
    (转载)Linux 僵尸进程与孤儿进程
    (转载)valgrind,好东西,一般人我不告诉他~~ 选项
    (转载)Linux进程组、作业、会话的理解
    Open a file, and then readin a file tcl tk
    save vars and arrays
    itcl class example
    constructor with args tcl tk
  • 原文地址:https://www.cnblogs.com/venow/p/2643701.html
Copyright © 2011-2022 走看看