数据结构(C++)AOE求关键路径

AOE图求关键路径,我们可以把他比作一个工程,后续的工程需要前面的工程做铺垫,等到前面的所有工作都结束之后才可以开展后续的工作,有向赋权图就可以完成这样的表示。从起点到终点的路径不只有一条,但是需要路径上全部的活动都完成后,整个工程才算结束。因此,完成整个工程所需的最短时间取决于从起点到终点的最长路径长度,即这条路径上所有活动持续时间之和。
这条路径长度最长的路径就是关键路径。
这副图就可以比作一个工程,v9 工程结束。
在这里插入图片描述
关键路径:在AOE网中,从始点到终点具有最大路径长度(该路径上的各个活动所持续的时间之和)的路径称为关键路径。
关键活动:关键路径上的活动称为关键活动。

事件发生最早时间v[k]

事件发生的最早时间可以表示为从起点到k顶点的最长路径。

void setve()
{
	int visited[MaxSize];
	queue<int>q;
	q.push(1);
	for (int i = 1; i <= vertexNum; ++i)
	{
		ve[i] = 0;
		visited[i] = 0;
	}
	visited[1] = 1;
	while (!q.empty())
	{
		int k = q.front();
		q.pop();
		for (int i = 1; i <= vertexNum; ++i)
		{
			if (arc[k][i] != INF && ve[k] + arc[k][i] > ve[i])
			{
				ve[i] = ve[k] + arc[k][i];
				if (visited[i] == 0)
					q.push(i);
				visited[i] = 1;
			}
		}
	}
}

事件发生的最迟时间

通过最长时间我们得到的整个工程的用时之后,把他赋给最后一个点的vl,通过最后一个点向前推进,最迟时间是最后一个点减路径长度的最小值。

void setvl()
{
	queue<int>q;
	int visited[MaxSize];
	q.push(vertexNum);
	for (int i = 1; i <= vertexNum; ++i)
	{
		vl[i] = ve[vertexNum];
		visited[i] = 0;
	}
	while (!q.empty())
	{
		int k = q.front();
		q.pop();
		for (int i = 0; i < vertexNum; i++)
		{
			if (arc[i][k] != INF && vl[k] - arc[i][k] < vl[i])
			{
				vl[i] = vl[k] - arc[i][k];
				if (!visited[i])
				{
					q.push(i);
				}
				visited[i] = 1;
			}
		}
	}
}

活动开始的最早时间e[i]

该活动起点的ve值

void sete()
{
	for (int i = 1; i <= arcNum; ++i)
	{
		edge[i].e = ve[edge[i].from];
	}
}

活动的最晚开始时间

该活动的终点vl值减去路径长度。

void setl()
{
	for (int i = 1; i <= arcNum; ++i)
	{
		edge[i].e = ve[edge[i].from];
		edge[i].i = vl[edge[i].to] - arc[edge[i].from][edge[i].to];
	}
}

实现的全部代码

#include<iostream>
#include<queue>
using namespace std;
const int MaxSize = 20;
const int INF = 0x3f;
int ve[MaxSize];
int vl[MaxSize];
int e[MaxSize];
int l[MaxSize];
struct Edge
{
	int from;
	int to;
	int e;
	int i;
};
class Graph
{
	int arcNum;
	int vertexNum;
	int arc[MaxSize][MaxSize];
	Edge edge[MaxSize];
public:
	Graph(int n, int e)
	{
		arcNum = e;
		vertexNum = n;
		for (int i = 1; i <= vertexNum; ++i)
		{
			for (int j = 1; j <= vertexNum; ++j)
			{
				if (i == j)
					arc[i][j] = 0;
				else
					arc[i][j] = INF;
			}
		}
		for (int i = 1; i <= arcNum; ++i)
		{
			int a, b, v;
			cin >> a >> b >> v;
			arc[a][b] = v;
			edge[i].from = a;
			edge[i].to = b;
		}
	}
	void setve()
	{
		int visited[MaxSize];
		queue<int>q;
		q.push(1);
		for (int i = 1; i <= vertexNum; ++i)
		{
			ve[i] = 0;
			visited[i] = 0;
		}
		visited[1] = 1;
		while (!q.empty())
		{
			int k = q.front();
			q.pop();
			for (int i = 1; i <= vertexNum; ++i)
			{
				if (arc[k][i] != INF && ve[k] + arc[k][i] > ve[i])
				{
					ve[i] = ve[k] + arc[k][i];
					if (visited[i] == 0)
						q.push(i);
					visited[i] = 1;
				}
			}
		}
	}
	void setvl()
	{
		queue<int>q;
		int visited[MaxSize];
		q.push(vertexNum);
		for (int i = 1; i <= vertexNum; ++i)
		{
			vl[i] = ve[vertexNum];
			visited[i] = 0;
		}
		while (!q.empty())
		{
			int k = q.front();
			q.pop();
			for (int i = 0; i < vertexNum; i++)
			{
				if (arc[i][k] != INF && vl[k] - arc[i][k] < vl[i])
				{
					vl[i] = vl[k] - arc[i][k];
					if (!visited[i])
					{
						q.push(i);
					}
					visited[i] = 1;
				}
			}
		}
	}
	void sete()
	{
		for (int i = 1; i <= arcNum; ++i)
		{
			edge[i].e = ve[edge[i].from];
		}
	}
	void setl()
	{
		for (int i = 1; i <= arcNum; ++i)
		{
			edge[i].e = ve[edge[i].from];
			edge[i].i = vl[edge[i].to] - arc[edge[i].from][edge[i].to];
		}
	}
	void getPoint()
	{
		int count = 0;
		for (int i = 1; i <= arcNum; ++i)
		{
			if (edge[i].e == edge[i].i)
			{
				cout << "v" << edge[i].from << " ";
				count = i;
			}
		}
		cout << "v" << edge[count].to;
	}
};
int main()
{
	int n, ee;
	cin >> n >> ee;
	Graph G(n, ee);
	G.setve();
	G.setvl();
	G.sete();
	G.setl();
	G.getPoint();
	return 0;
}
  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值