请设计int pathNum(AOENetwork g)函数。 该函数返回AOE网g中关键路径数目。 已知点表中第一个点是源点,最后一个点是汇点,并且事件和活动的时间都已经计算好。c语言
时间: 2024-03-23 07:38:46 浏览: 50
C语言求AOE网关键路径
4星 · 用户满意度95%
以下是设计的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100 // 最大顶点数
#define INFINITY 65535 // 无穷大
typedef struct ArcNode { // 弧结点
int adjvex; // 该弧指向的顶点位置
int weight; // 弧上的权值
struct ArcNode *nextarc; // 指向下一条弧的指针
} ArcNode;
typedef struct VNode { // 顶点结点
int data; // 顶点信息
ArcNode *firstarc; // 指向第一条依附该顶点的弧的指针
} VNode, AdjList[MAX_VERTEX_NUM];
typedef struct { // AOE网
AdjList vertices; // 图中顶点及其各自的弧链表
int vexnum, arcnum; // 顶点数和弧数
} AOENetwork;
// 拓扑排序
int TopoSort(AOENetwork g, int ve[], int vl[]) {
int i, j, k, count = 0;
int indegree[MAX_VERTEX_NUM];
ArcNode *p;
// 初始化入度数组
for (i = 0; i < g.vexnum; i++) {
indegree[i] = 0;
}
// 计算每个顶点的入度
for (i = 0; i < g.vexnum; i++) {
p = g.vertices[i].firstarc;
while (p) {
indegree[p->adjvex]++;
p = p->nextarc;
}
}
// 初始化ve数组
for (i = 0; i < g.vexnum; i++) {
ve[i] = 0;
}
// 拓扑排序
int *stack, top = -1;
stack = (int *) malloc(g.vexnum * sizeof(int)); // 栈
for (i = 0; i < g.vexnum; i++) { // 初始化栈
if (indegree[i] == 0) {
stack[++top] = i;
}
}
while (top != -1) {
i = stack[top--];
count++;
for (p = g.vertices[i].firstarc; p; p = p->nextarc) {
j = p->adjvex;
if (--indegree[j] == 0) {
stack[++top] = j;
}
if (ve[i] + p->weight > ve[j]) {
ve[j] = ve[i] + p->weight;
}
}
}
free(stack);
if (count < g.vexnum) { // 有环
return 0;
}
// 初始化vl数组
for (i = 0; i < g.vexnum; i++) {
vl[i] = ve[g.vexnum - 1];
}
// 求vl数组
for (i = g.vexnum - 2; i >= 0; i--) {
k = 0;
for (p = g.vertices[i].firstarc; p; p = p->nextarc) {
j = p->adjvex;
if (vl[j] - p->weight < vl[i]) {
vl[i] = vl[j] - p->weight;
k = j;
}
}
}
return 1;
}
// 关键路径数目
int pathNum(AOENetwork g) {
int ve[MAX_VERTEX_NUM], vl[MAX_VERTEX_NUM];
int i, cnt = 0;
ArcNode *p;
if (!TopoSort(g, ve, vl)) { // 有环
return 0;
}
for (i = 0; i < g.vexnum; i++) {
p = g.vertices[i].firstarc;
while (p) {
if (ve[i] == vl[p->adjvex] - p->weight) { // 关键路径上的活动
cnt++;
}
p = p->nextarc;
}
}
return cnt;
}
int main() {
AOENetwork g;
int i, m, n, w;
scanf("%d%d", &n, &m);
g.vexnum = n;
g.arcnum = m;
// 建立AOE网
for (i = 0; i < g.vexnum; i++) { // 初始化顶点信息和指针
g.vertices[i].data = i;
g.vertices[i].firstarc = NULL;
}
for (i = 0; i < g.arcnum; i++) { // 建立弧
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
ArcNode *p = (ArcNode *) malloc(sizeof(ArcNode));
p->adjvex = v;
p->weight = w;
p->nextarc = g.vertices[u].firstarc;
g.vertices[u].firstarc = p;
}
printf("%d\n", pathNum(g));
return 0;
}
```
其中,TopoSort函数用于进行拓扑排序,求出每个顶点的最早开始时间ve和最晚开始时间vl,且返回是否有环的信息;pathNum函数用于求出关键路径数目,方法是遍历每个活动,判断其是否在关键路径上。
阅读全文