#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