问题与解答
问题描述
计算AOE-网中关键路径的长度。
输入格式
输入数据第一行是一个正整数,表示图中的顶点个数n(顶点将分别按0,1,…,n-1进行编号),顶点数不超过100,其中0为源点,n-1为汇点。之后的n行每行都包含n个整数,为AOE-网的邻接矩阵,其中0表示两个顶点间无直接可达的弧,大于0的整数表示活动持续的时间。
输出格式
输出AOE-网中关键路径的长度,如果网中有环,则输出“NO”。
样例输入
9
0 6 4 5 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 9 7 0
0 0 0 0 0 0 0 4 0
0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 4
0 0 0 0 0 0 0 0 0
样例输出
18
输出说明:
如果网中有环,则示例输出如下:NO
//求解关键路径长度
//只需要求关键路径长度,不需要打印关键路径
//所以只需要在TopoSort()上进行改进即可
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
#define MaxN 100 //最大顶点数
int n; //顶点数
int G[MaxN][MaxN]; //邻接矩阵保存图
int InDegree[MaxN] = {0}, Ve[MaxN]; //入度矩阵
//Ve数组:事件最早开始时间,初始化为0
int TopoSort(); //拓扑排序
int main(){
int i,j,w;
scanf("%d",&n);
for(i = 0; i < n; i++){ //读入邻接矩阵
for(j = 0; j < n; j++){
scanf("%d",&w);
G[i][j] = w;
if(w) InDegree[j]++; //j顶点入度+1
}
}
int Path_Length = TopoSort();
if(Path_Length == -1) printf("No");
else printf("%d", Path_Length);
}
int TopoSort(){ //改动后的拓扑排序,返回关键路径长度
fill(Ve,Ve+n,0); //初始化Ve数组
queue<int> q;
int i,node;
for(i = 0; i < n; i++){
if(InDegree[i] == 0)
q.push(i);
}
while(!q.empty()){
int u = q.front();
q.pop();
for(i = 0; i < n; i++){
if(G[u][i] != 0){
InDegree[i]--;
if(InDegree[i] == 0)
q.push(i);
//更新Ve数组:在原TopoSort()基础上添加的部分
if(Ve[u] + G[u][i] > Ve[i])
Ve[i] = Ve[u]+G[u][i];
}
}
node++;
}
if(node !=n) return -1; //存在有向环,拓扑排序失败
else return Ve[n-1]; //拓扑排序成功,返回关键路径长度
}
题后反思
- 本题只需要求解关键路径的长度而不需要确定关键路径的具体节点,所以只需要建立Ve数组即可,不需要用逆拓扑排序建立Vl求e与l。
- 注意点:实现时默认存在源点与汇点,汇点为 n-1 号顶点(从0开始计)。
- 关键路径完整算法