#include <iostream>
#include <stack>
#include <stdio.h>
using namespace std;
#define MAX_VERTEX_NUM 100
using namespace std;
typedef char v_type;
typedef struct ArcNode {
int adjvex;
struct ArcNode *nextarc;
int weight;
}ArcNode;
typedef struct VNode {
v_type data;
int indegree;
ArcNode *firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vexs;
int vexnum,arcnum;
}ALGraph;
//------------------定位函数---------------------
int LocateVex(ALGraph G, v_type u) {
int i;
for (i=0; i<G.vexnum; i++) {
if (u==G.vexs[i].data) return i;
}
if (i==G.vexnum) {
cout << "Error!" ;
exit (1);
}
}
//---------------creat graph------------------
void CreatALGraph(ALGraph &G) {
int i,j,k,w;
ArcNode *p;
v_type v1,v2;
cout << "Input vexnum & arcnum:" ;
cin >> G.vexnum >> G.arcnum;
cout << "Input vertices" ;
for (i=0; i<G.vexnum; i++) {
cin >> G.vexs[i].data ;
G.vexs[i].indegree = 0;
G.vexs[i].firstarc = NULL;
}
for (k=0; k<G.arcnum; k++) {
cout << "Input arcs(v1, v2 & w):" ;
cin >> v1 >> v2 >> w ;
i = LocateVex(G, v1);
j = LocateVex(G, v2);
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = G.vexs[i].firstarc;
p->weight = w;
G.vexs[i].firstarc = p;
++G.vexs[j].indegree;
}
}
//-------------top logical sort---------------------
bool TopLogicalSort(ALGraph G) {
ArcNode *p;
int i,k;
int top = -1;
int count = 0;
for (i=0; i<G.vexnum; i++) {
if (G.vexs[i].indegree == 0) {
G.vexs[i].indegree = top;
top = i;
}
}
while (top+1) {
i = top;
top = G.vexs[i].indegree;
cout << G.vexs[i].data << ' ';
count++;
for (p=G.vexs[i].firstarc; p; p=p->nextarc) {
k = p->adjvex;
G.vexs[k].indegree--;
if (G.vexs[k].indegree==0) {
G.vexs[k].indegree = top;
top = k;
}
}
}
cout << endl;
if (count<G.vexnum) return false;
else return true;
}
//-------------------关键路径--------------------
void CriticalPath(ALGraph G) {
if (!TopLogicalSort(G)) exit(0); //如果不满足拓扑,有可能会造成逻辑错误
int i,j,k,e,l;
int *Ve,*Vl;
ArcNode *p;
//顶点代表事件
Ve = new int[G.vexnum]; //代表事件V[i]最早可能发生时间
Vl = new int[G.vexnum]; //代表事件V[i]最迟允许开始时间
for (i = 0; i < G.vexnum; ++i) { //初始化Ve数组
Ve[i] = 0;
}
for (i = 0; i < G.vexnum; ++i) { //给Ve数组赋值
p = G.vexs[i].firstarc;
while (p != NULL) {
k = p->adjvex;
if (Ve[i] + p->weight > Ve[k])
Ve[k] = Ve[i] + p->weight;
p = p->nextarc;
}
}
for (i = 0; i < G.vexnum; ++i) { //初始化Vl数组
Vl[i] = Ve[G.vexnum-1];
}
for (i = G.vexnum-2; i; --i) { //给Vl数组赋值
p = G.vexs[i].firstarc;
while (p != NULL) {
k = p->adjvex;
if (Vl[k] - p->weight < Vl[i])
Vl[i] = Vl[k] - p->weight;
p = p->nextarc;
}
}
for (i = 0; i < G.vexnum; ++i) {
p = G.vexs[i].firstarc;
while (p != NULL) {
k = p->adjvex;
//边代表活动
e = Ve[i]; //代表活动a[i]最早可能发生时间
l = Vl[k] - p->weight; //代表活动a[i]最迟允许开始时间
char tag = (l-e==0)?'*':' '; //带星号的顶点代表可以作为关键路径上的点
printf("(%c, %c), e=%d, l=%d, %c/n",
G.vexs[i].data, G.vexs[k].data, e, l, tag);
p = p->nextarc;
}
}
}
int main() {
ALGraph G;
CreatALGraph(G);
CriticalPath(G);
system("pause");
return 0;
}