【问题描述】若在带权的有向图中,以顶点表示事件,以有向边表示活动,边上的权值表示活动的开销(如该活动持续的时间),则此带权的有向图称为AOE网。如果用AOE网来表示一项工程,那么,仅仅考虑各个子工程之间的优先关系还不够,更多的是关心整个工程完成的最短时间是多少;哪些活动的延期将会影响整个工程的进度,而加速这些活动是否会提高整个工程的效率。因此,通常在AOE网中列出完成预定工程计划所需要进行的活动,每个活动计划完成的时间,要发生哪些事件以及这些事件与活动之间的关系,从而可以确定该项工程是否可行,估算工程完成的时间以及确定哪些活动是影响工程进度的关键。
【输入形式】第一行输入两个数字,分别表示顶点数和边数;从第二行开始,输入边的信息,格式为(i,j, weight)
【输出形式】关键路径的总时间(最大路径长度),代表关键活动的边,格式为(顶点1,顶点2),按大小顺序排列
【样例输入】
6 8
0 1 3
0 2 2
1 3 2
1 4 3
2 3 4
2 5 3
3 5 2
4 5 1
【样例输出】
8
0 2
2 3
3 5
#include<iostream>
#include<stack>
#include<vector>
#define maxsize 50
using namespace std;
int n;//顶点个数
int m;//边的条数(活动个数)
int indegree[maxsize];//入度
int ve[maxsize];//事件开始最找时间
int vl[maxsize];//事件开始最晚时间
//int e[maxsize];//活动开始最早时间
//int l[maxsize];//活动开始最晚时间
//int d[maxsize];//活动的松弛时间,为0则为关键活动
int g[maxsize][maxsize];//邻接矩阵
int longestPath;//最长路径的长度
stack<int>s1, s2;//分别用于拓扑序列与逆拓扑序列
vector<int>v;//存储关键路径,便于输出
void initGraph()
{
for (int i = 0; i < m; i++)
{
int v1, v2, weight;
cin >> v1 >> v2 >> weight;
g[v1][v2] = weight;
indegree[v2]++;
}
}
void topologicalSort()
{
fill(ve, ve + maxsize, 0);//初始化最早发生时间
for (int i = 0; i < n; i++)
{
if (indegree[i] == 0)
{
s1.push(i);
}
}
while (!s1.empty())
{
int top = s1.top();
s2.push(top);//存放逆拓扑序列
s1.pop();
for (int i =0; i < n; i++)
{
if (g[top][i]!=32767)
{
indegree[i]--;
if (indegree[i] == 0)
{
s1.push(i);
}
//按拓扑序列计算事件最早发生时间
if (g[top][i]+ve[top] > ve[i])//注意
{
ve[i] = g[top][i]+ve[top];
}
}
}
}
}
void CriticalPath()//关键路径
{
//计算vl[i]//时间发生的最晚时间
for (int i = 0; i < n; i++)
{
vl[i] = ve[n - 1];//将各顶点时间最晚发生时间初始化为汇点的最早发生时间
}
while (!s2.empty())
{
int top = s2.top();
s2.pop();
for (int i = 0; i < n; i++)
{
if (g[top][i] != 32767)
{
if (vl[i]-g[top][i] < vl[top])
{
vl[top] = vl[i]-g[top][i];
}
}
}
}
//计算e[i],l[i]和关键活动
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (g[i][j]!= 32767)
{
int ei = ve[i];
int li = vl[j] - g[i][j];
if (ei == li)
{
v.push_back(i);
v.push_back(j);
}
}
}
}
}
void printAns()
{
longestPath = ve[n - 1];
cout << longestPath << endl;
for (int i = 0; i < (signed)v.size(); i++)
{
cout << v[i] << " ";
if (i % 2 ==1)
{
cout << endl;
}
}
}
int main()
{
cin >> n >> m;
fill(indegree, indegree + maxsize, 0);
fill(g[0], g[0] + maxsize * maxsize, 32767);
initGraph();
topologicalSort();
CriticalPath();
printAns();
//system("pause");
return 0;
}