关键路径,C++实现,图用邻接矩阵存储

//关键路径,利用拓扑排序求解关键路径(图的邻接矩阵存储)
//关键路径即整个图中从起点到终点的最长距离,我们把顶点称为事件,边称为活动
//求解关键路径即求出所有事件的最早开始时间和最晚开始时间(假设总时长不推迟)
//若一活动的起点事件的最早开始时间=该活动终点事件的最晚开始时间-活动持续时间,该活动为关键活动
//关键路径上的所有活动都是关键活动

#include<iostream>
#include<stdlib.h>
#include<stack>
using namespace std;
#define MAX_VERTEX 10
#define MAX_WEIGHT 100

//邻接矩阵
typedef struct
{
	int weight;
}AdjMatrix[MAX_VERTEX][MAX_VERTEX];

//图
struct Graph
{
	int* head;
	AdjMatrix adj;
	int vn;
	int en;
};

//给顶点数据返回顶点下标
int Located(Graph g, int x)
{
	for (int i = 0; i < g.vn; i++)
		if (g.head[i] == x)
			return i;
	return 100;
}

//邻接矩阵存储
void CreateGraph(Graph& g)
{
	g.head = (int*)malloc(MAX_VERTEX * sizeof(int));
	cout << "Input vertex numbers and edge numbers: ";
	cin >> g.vn >> g.en;
	for (int i = 0; i < g.vn; i++)
		for (int j = 0; j < g.vn; j++)
			g.adj[i][j].weight = MAX_WEIGHT;

	//输入顶点与边
	cout << "Input vertexs: " << endl;
	for (int i = 0; i < g.vn; i++)
		cin >> g.head[i];
	for (int i = 0; i < g.en; i++)
	{
		cout << "Input the vertexs and the weight of the edge" << endl;
		int a, b,w;
		cin >> a >> b>>w;
		g.adj[Located(g, a)][Located(g, b)].weight = w;
	}
}

int InDegree[MAX_VERTEX];//入度数
int ve[MAX_VERTEX];//事件最早发生时间
int vl[MAX_VERTEX];//事件最晚发生时间
//初始化入度
void FindInDegree(Graph g)
{
	for (int i = 0; i < g.vn; i++)
		InDegree[i] = 0;
	for (int i = 0; i < g.vn; i++)
		for (int j = 0; j < g.vn; j++)
			if(g.adj[i][j].weight!=MAX_WEIGHT)
				InDegree[j]++;
}

//为配合求关键路径而修改过的拓扑排序
void TopoLogicalSort(Graph g,stack<int>&t)
{
	stack<int>s;
	FindInDegree(g);
	for (int i = 0; i < g.vn; i++)
		ve[i] = 0;
	//将所有入度为0的顶点下标入栈
	for (int i = 0; i < g.vn; i++)
		if (!InDegree[i])
			s.push(i);
	while (!s.empty())
	{
		int v = s.top();
		s.pop();

		//将本应打印的顶点入栈,构造逆拓扑排序,为关键路径函数中从拓扑排序最后开始倒推vl做准备
		t.push(v);

		//将该顶点周边一圈顶点的入度-1,若有减完入度为0的直接入栈
		for (int i = 0; i < g.vn; i++)
			if (g.adj[v][i].weight != MAX_WEIGHT)
			{
				if (!(--InDegree[i]))
					s.push(i);
				//初始化ve
				if (ve[i] < ve[v] + g.adj[v][i].weight)
					ve[i] = ve[v] + g.adj[v][i].weight;
			}
	}
}

void CriticalPath(Graph g)
{
	stack<int>t;
	TopoLogicalSort(g,t);

	//初始化vl为终点所用时间(最大值)
	for (int i = 0; i < g.vn; i++)
		vl[i] = ve[t.top()];
	t.pop();

	//通过逆拓扑排序求vl
	while(!t.empty())
	{
		int j = t.top();
		t.pop();
		for (int k = 0; k < g.vn; k++)
			if (g.adj[j][k].weight != MAX_WEIGHT && vl[j] > vl[k] - g.adj[j][k].weight)
				vl[j] = vl[k] - g.adj[j][k].weight;
	}

	//打印关键活动(连起来就是关键路径)
	cout << "Following critical activities:" << endl;
	for (int i = 0; i < g.vn; i++)
		for (int j = 0; j < g.vn; j++)
			if (g.adj[i][j].weight != MAX_WEIGHT && ve[i] == vl[j] - g.adj[i][j].weight)
				cout <<"from "<< g.head[i] << " to " << g.head[j] << endl;
}

int main()
{
	Graph g;
	CreateGraph(g);
	CriticalPath(g);
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值