[数据结构]AOE网 关键活动 关键路径

学习记录~~

 

#include<iostream>
using namespace std;

const int MaxSize = 100;
const int MaxInt = 32767;
typedef string DataType;
const int MaxEdge = 100;
struct EdgeNode
{
	int adjvex;
	int weight;
	EdgeNode* next;
};
struct VertexNode
{
	DataType vertex;//顶点信息
	int in_Top_Num;//每个顶点入度(求拓扑序列时会递减)
	int inNum;//每个顶点入度
	int in[MaxSize];//狐尾顶点的下标
	int outNum;//每个顶点出度
	int out[MaxSize];//狐头顶点的下标
	EdgeNode* firstEdge;
};
struct EdgeType
{
	int from, to;
	int weigth;
};
class ALGraph
{
private:
	EdgeType edge[MaxEdge];//边集数组
	VertexNode adjList[MaxSize];
	int vertexNum, edgeNum;
	int Max(int i);
	int Min(int i);
public:
	ALGraph(DataType a[], int n, int e);
	~ALGraph();
	int *TopSort();//返回拓扑序列下标
	void CriticalPath(int *Top);
};
int vl[MaxSize], ve[MaxSize], ee[MaxSize], el[MaxSize],el_ee[MaxSize];
/*
0 1 4
0 2 3
1 2 2
2 3 4
1 3 6
*/
int main()
{
	DataType s[] = { "v0","v1","v2","v3" };
	ALGraph G(s, 4, 5);
	
	G.CriticalPath(G.TopSort());
	return 0;
}

ALGraph::ALGraph(DataType a[], int n, int e)
{
	vertexNum = n;
	edgeNum = e;
	int i, j, k, w=0;
	int* rd = new int[vertexNum];
	int* cd = new int[vertexNum];
	for (i = 0; i < vertexNum; i++)
		cd[i] = rd[i] = 0;
	for (i = 0; i < vertexNum; i++)
	{
		adjList[i].vertex = a[i];
		adjList[i].firstEdge = NULL;
		adjList[i].in_Top_Num = 0;
		adjList[i].inNum = 0;
		adjList[i].outNum = 0;
	}
	for (k = 0; k < edgeNum; k++)
	{
		cin >> i >> j >> w;

		EdgeNode* s = new EdgeNode;
		s->adjvex = j;
		s->weight = w;
		s->next = adjList[i].firstEdge;
		adjList[i].firstEdge = s;

		adjList[j].in_Top_Num++;
		adjList[j].inNum++;
		adjList[j].in[rd[j]++] = i;//j顶点的入度加一后这里把以j顶点做狐头的狐的狐尾顶点的下标存起来
		adjList[i].outNum++;
		adjList[i].out[cd[i]++] = j;//i顶点的出度加一后这里把以i顶点做为狐尾的狐的狐头的下标存起来

		edge[k].from = i;
		edge[k].to = j;
		edge[k].weigth = w;
	}
	delete[]rd;
	delete[]cd;
}

ALGraph::~ALGraph()
{
	int i, j;
	EdgeNode* p = NULL, * q = NULL;
	for (i = 0; i < vertexNum; i++)
	{
		p = q = adjList[i].firstEdge;
		while (p != NULL)
		{
			p = p->next;
			delete q;
			q = p;
		}
	}
}

int* ALGraph::TopSort()
{
	int Start[MaxSize],top=-1;
	int *topxl=new int[MaxSize];//保存拓扑序列下标
	int i, j, k, count = 0;
	EdgeNode* p = NULL;
	for (i = 0; i < vertexNum; i++)
	{
		if (adjList[i].in_Top_Num==0)
			Start[++top] = i;
	}
	while (top != -1)
	{
		j = Start[top--];
		cout << adjList[j].vertex<<" ";
		topxl[count++] = j;
		p = adjList[j].firstEdge;
		while (p != NULL)
		{
			k = p->adjvex;
			adjList[k].in_Top_Num--;
			if (adjList[k].in_Top_Num == 0)
				Start[++top] = k;
			p = p->next;
		}
		
	}
	if (count == vertexNum)
		return topxl;
	if (count < vertexNum)
	{
		cout << "有回路\n";
		return NULL;
	}
	delete[]topxl;
}
int ALGraph::Max(int i)
{
	int max_ve =-1,w=0;
	for (int j = 0; j < adjList[i].inNum; j++)
	{
		for (int k = 0; k < edgeNum; k++)
		{
			if (edge[k].to == i && edge[k].from == adjList[i].in[j])
			{
				w = edge[k].weigth;
				break;
			}

		}
		if (ve[adjList[i].in[j]] + w > max_ve)
			max_ve = ve[adjList[i].in[j]] + w;
	}
	return max_ve;
}
int ALGraph::Min(int i)
{
	int w, min_vl=MaxInt;
	for (int j = 0; j < adjList[i].outNum; j++)
	{
		for (int k = 0; k < edgeNum; k++)
		{
			if (edge[k].from == i && edge[k].to == adjList[i].out[j])
			{
				w = edge[k].weigth;
				break;
			}
		}
		if (vl[adjList[i].out[j]] - w < min_vl)
			min_vl = vl[adjList[i].out[j]] - w;
	}
	return min_vl;
}
void ALGraph::CriticalPath(int* Top)
{
	int i, j = 0, w = 0;
	cout << "\n拓扑序列为\n";
	for (i = 0; i < vertexNum; i++)
		cout << adjList[Top[i]].vertex << " ";
	cout << endl;
	for (i = 0; i < vertexNum; i++)
	{
		if (i == 0)
			ve[Top[i]] = 0;
		else
			ve[Top[i]] = Max(Top[i]);
		cout << "顶点" << adjList[Top[i]].vertex << "的最早发生时间ve=" << ve[Top[i]] << endl;
	}
	cout << endl;
	for (i = vertexNum - 1; i >= 0; i--)
	{
		if (i == vertexNum - 1)
			vl[Top[i]] = ve[Top[i]];
		else
			vl[Top[i]] = Min(Top[i]);
		cout << "顶点" << adjList[Top[i]].vertex << "的最迟发生时间vl=" << vl[Top[i]] << endl;
	}
	cout << endl;
	for (j = 0; j < edgeNum; j++)
	{
		ee[j] = ve[edge[j].from];
		el[j] = vl[edge[j].to] - edge[j].weigth;
		el_ee[j] = el[j] - ee[j];
	}
	for (j = 0; j < edgeNum; j++)
		cout << "下标为" << j << "的边的最早发生时间ee=" << ee[j] << endl;
	cout << endl;
	for (j = 0; j < edgeNum; j++)
		cout << "下标为" << j << "的边的最迟发生时间el=" << el[j] << endl;
	cout << endl;
	cout << "时间余量为0的边为关键活动\n";
	for (j = 0; j < edgeNum; j++)
		cout << "下标为" << j << "的边的时间余量el-ee=" << el_ee[j] << endl;
	cout << endl;
	int sum = vl[Top[vertexNum - 1]];
	w = 0;
	cout << "关键路径为为:\n";
	for (i = 0; i < edgeNum; i++)
	{
		if (w == sum)
			break;
		if (el_ee[i] == 0)
		{
			cout << "("<<adjList[edge[i].from].vertex << " ";
			cout << edge[i].weigth<<" ";
			cout << adjList[edge[i].to].vertex << ")";
			w+= edge[i].weigth;
		}
	}
}

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值