Graph.h
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include <iostream>
#include <cstdlib>
using namespace std;
//链表结构
typedef struct ListNode {
int index;
int weight;
struct ListNode *next;
}ListNode;
//顶点结构
typedef struct Vertex{
int indegree;
ListNode *firstvex;
char data;
}Vertex;
//图结构
typedef struct Graph{
Vertex vertex[256];
int vexnum , edgenum;
}Graph;
void Init(Graph &G);
void Create_Graph(Graph &G);
void Init(Graph &G){
G.edgenum = 0;
G.vexnum = 0;
}
void Create_Graph(Graph &G){
cout << "请输入顶点数:" ;
cin >> G.vexnum;
cout << "请输入边数:";
cin >> G.edgenum;
int i , j , k;
//第0号位置不用,输入顶点
for (i = 1 ; i <= G.vexnum ; i++){
cout << "第" << i << "个顶点为:";
cin >> G.vertex[i].data;
G.vertex[i].firstvex = NULL;
G.vertex[i].indegree = 0;
}
//输入边
int weight;
for(int k = 0 ; k < G.edgenum ; k++){
cout << "请输入边(vi , vj)的下标i,j:";
cin >> i >> j;
cout << "请输入(" << i << "," << j << ")的权值: ";
cin >> weight;
//构造边即将顶点下标存入链结构中
//前插法,尾插法需要遍历好麻烦
ListNode *e = new ListNode;
e->index = j;
e->next = G.vertex[i].firstvex;
e->weight = weight;
G.vertex[i].firstvex = e;
G.vertex[j].indegree++;
}
}
#endif // GRAPH_H_INCLUDED
#ifndef KEYPATH_H_INCLUDED
#define KEYPATH_H_INCLUDED
#include <iostream>
#include "Graph.h"
#include <stack>
using namespace std;
//拓扑逆序栈
stack<int> T;
//入度为零节点栈
stack<int> S;
int ve[256];
int vl[256];
//拓扑排序
bool TopologicalOrder(Graph G){
//记录入度为零的顶点
int count = 0;
int i;
//初始化时间最早发生时间为0
for(i = 1 ; i <= G.vexnum ; i++){
ve[i] = 0;
}
//将起点入零入度栈
S.push(1);
ListNode *p;
int j , k;
while(!S.empty()){
j = S.top();
S.pop();
T.push(j);
count++;
//深度遍历当前入度为零的节点,将其相邻节点的入度减一
for( p = G.vertex[j].firstvex ; p ; p = p->next){
k = p->index;
//相邻节点入度减为零则入栈
if(--G.vertex[k].indegree == 0){
S.push(k);
}
//事件k的最早开始时间是前一个相邻节点最早发生时间
//加上路径权值中最大的那个即MAX{ve[j] + weight}
if(ve[j] + p->weight > ve[k]){
ve[k] = ve[j] + p->weight;
}
}
}
if(count < G.vexnum){
return false;
}
else return true;
}
void CriticalPath(Graph G){
if(!TopologicalOrder(G)){
cout << "没有拓扑路径";
exit(1);
}
int i;
//初始化将最晚发生时间赋值为终点的最晚发生时间
//因为终点最晚发生时间与最早发生时间一致且为最大值
for(i = 1 ; i <= G.vexnum ; i++){
vl[i] = ve[G.vexnum];
}
while(!T.empty()){
//j,k代表边<j , k>
int j = T.top();
T.pop();
ListNode *p;
int k;
//第一次终点的相邻节点为NULL不执行
for(p = G.vertex[j].firstvex ; p ; p = p->next){
k = p->index;
if(vl[k] - p->weight < vl[j]){
vl[j] = vl[k] - p->weight;
}
}
}
int k , j;
ListNode *p;
for(j = 1 ; j <= G.vexnum ; j++){
//第一种方法判断关键路径
// for(p = G.vertex[j].firstvex ; p ; p = p->next){
// k = p->index;
// int ee = ve[j];
// int el = vl[k] - p->weight;
// if(ee == el){
// cout << G.vertex[j].data << " ";
// }
// }
//第二种方法判断关键路径
if(ve[j] == vl[j]){
cout << G.vertex[j].data << " ";
}
}
// cout << G.vertex[G.vexnum].data;
}
#endif // KEYPATH_H_INCLUDED
#include <iostream>
#include "Graph.h"
#include "KeyPath.h"
using namespace std;
int main()
{
Graph G;
Init(G);
Create_Graph(G);
CriticalPath(G);
}