Data structure-critical path AOV (Figure)

In a directed graph, vertices represent events , directed edges represent activities , and the weights on the edges represent the duration of the activities .

Critical path : The duration of the activity is also called the path length, and the path with the maximum length from the source point to the end point is called the critical path.

The critical path can be understood as an event at the same level, and the maximum time taken up, then the critical path must pass through this event.

The latest start time of the activity is equal to the latest start time, then the activity is a critical activity, and the path of the activity is the critical path

etv: the earliest time
when the event occurred ltv: the latest time when the event occurred
ete: the earliest start time of the
event lte: the latest start time of the event

etv is to find the earliest occurrence time of the event, in fact, it is to find the sum of the maximum weight of the previous path.
Because only all events have occurred, the next event can begin to occur, that is, the earliest start time of the event

And ltv is to find the latest occurrence time of the event, that is, as long as the big event has not ended, it can happen before the time on its own edge weight. It is to push the time backward and subtract the corresponding edge weight.

The latest occurrence time of the activity lte: is the latest occurrence of the event, minus the duration of the edge. The
earliest occurrence time of the activity: is the earliest occurrence of the event.

When the earliest occurrence time of the activity and the latest occurrence time of the activity are equal, the arc where the activity is located is the critical path.

#include<iostream>
using namespace std;
#define MAX 25

typedef char Vertype;
typedef int Edgetype;
typedef int Status;

//构造图的有向图的邻接表结构体
typedef struct EdgeNode//边表结点  存放每个顶点的邻接点
{
    
    
	int adjvex;//边表下标
	Edgetype weight;//边表权重  若边不存在时即无NULL
	struct EdgeNode *next;//指向下一个邻接点
}EdgeNode;

typedef struct VerNode//顶点表   存放顶点
{
    
    
	int in;
	Vertype data;//顶点元素
	EdgeNode *firstedge;
}VerNode, AdjList[MAX];//邻接表的 顶点元素 和指向邻点的指针

typedef struct
{
    
    
	AdjList adjList;//邻接表
	int numVer, numEdge;//顶点数目和边的数目
}GraphAdjList;

//构造两个栈
typedef struct Stack
{
    
    
	int data[MAX];
	//int pop;
}SqStack;

//生成邻接表
Status CreatGraph(GraphAdjList &G)
{
    
    
	int i, j, k;
	Edgetype w;
	EdgeNode *e;
	cout << "Enter the number of vertices :" << endl;
	cin >> G.numVer;
	cout << "Enter the number of Edges :" << endl;
	cin >> G.numEdge;

	cout << "Input vertex content :" << endl;
	for (i = 0; i < G.numVer; i++)
	{
    
    
		cin >> G.adjList[i].data;//输入顶点元素
		G.adjList[i].in = 0;
		G.adjList[i].firstedge = NULL;//初始化邻边表为NULL;
	}

	for (k = 0; k < G.numEdge; k++)
	{
    
    
		cout << "Enter the vertex number of the edge (Vi->Vj)" << endl;
		cin >> i;
		cin >> j;

		cout << "Enter the weight of edge" << i << "-" << j << endl;
		cin >> w;
		e = new EdgeNode;//将两个顶点相结即可。
		e->adjvex = j;// 邻接序号为j
		e->next = G.adjList[i].firstedge;//i的第一个邻接指针 为e的指针
		e->weight = w;
		G.adjList[i].firstedge = e;
		G.adjList[j].in++;

		//有向图则只有生成一次即可
		/*
		e = new EdgeNode;
		e->adjvex = i;//无向图 重复一遍
		e->next = G.adjList[j].firstedge;
		G.adjList[j].firstedge = e;
		e->weight = w;*/
	}
	return 0;
}


SqStack *etv, *stack2;
SqStack *ltv;/*事件最晚发生时间*/
int top2;
//拓扑排序
Status TOpologicalSort(GraphAdjList &G)
{
    
    
	EdgeNode *e;
	//SqStack Q;
	int i, j, k, gettop;
	int top = 0;
	int count = 0;

	SqStack *Q;
	Q = new SqStack;
	for (i = 0; i < G.numVer; i++)
	{
    
    
		if (G.adjList[i].in == 0)
			Q->data[++top] = i;//存放入度为0的顶点
	}

	top2 = 0;/*初始化 事件最早发生的时间为0*/
	//SqStack *etv,*stack2;
	etv = new SqStack;
	for (i = 0; i < G.numVer; i++)
	{
    
    
		etv->data[i] = 0;
	}

	stack2 = new SqStack;
	while (top != 0)
	{
    
    
		gettop = Q->data[top--];//弹出入度为0的下标
		stack2->data[++top2] = gettop;//按照拓扑顺序保存弹出顶点下标
		count++;//统计拓扑网顶点数目

		//后面输出其边顶点
		//并删除边,使得边顶点入度-1
		for (e = G.adjList[gettop].firstedge; e; e = e->next)
		{
    
    
			j = e->adjvex;
			if (!(--G.adjList[j].in))//如果入度为1时  自减后进入循环   如果入度不为1,自减后 相当于边的数目减1
			{
    
    
				Q->data[++top] = j;//保存后续入度为0的顶点
			}

			/**/
			if ((etv->data[gettop] + e->weight) > etv->data[j])
			{
    
    
				etv->data[j] = etv->data[gettop] + e->weight;//保存权值   etv初始化都为0,
			}
		}
	}
	if (count < G.numVer)
	{
    
    
		cout << "不是一个网图" << endl;
		return 1;
	}
	else
	{
    
    
		cout << "是一个网图" << endl;
		return 0;
	}
	//return 0;

}

Status CriticalPath(GraphAdjList &G)
{
    
    
	EdgeNode *e;
	int i, j, k, gettop;
	int ete, lte;/*活动最早发生时间ele  活动最迟发生时间lte*/
	
	
	ltv = new SqStack;
	/*初始化ltv*/
	for (i = 0; i < G.numVer; i++)
	{
    
    
		ltv->data[i] = etv->data[G.numVer - 1];
	}
	while (top2 != 0)
	{
    
    
		gettop = stack2->data[top2--];
		for (e = G.adjList[gettop].firstedge; e; e = e->next)
		{
    
    
			k = e->adjvex;
			if (ltv->data[k] - e->weight < ltv->data[gettop])
			{
    
    
				ltv->data[gettop] = ltv->data[k] - e->weight;
			}
		}
	}
	for (j = 0; j < G.numVer; j++)
	{
    
    
		for (e = G.adjList[j].firstedge; e; e = e->next)
		{
    
    
			k = e->adjvex;
			ete = etv->data[j];
			lte = ltv->data[k] - e->weight;
			if (ete == lte)
			{
    
    
				cout <<G.adjList[j].data<<G.adjList[k].data<<e->weight << endl;
			}
		}
	}
	return 0;
}

int main()
{
    
    
	GraphAdjList G;
	CreatGraph(G);
	TOpologicalSort(G);
	CriticalPath(G);
	system("pause");
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_46096297/article/details/113894709