用c语言写一个输出关键路径 功能描述:根据创建的有向图及权重,调用TopologicalSort函数应用栈结构输出关键路径。 输出格式printf("Criticalpath: <%d,%d> length: %d\n", 开始节点数组index下标, 下一节点数组index下标, 权重);
时间: 2024-02-26 17:52:26 浏览: 72
关键路径的算法设计与实现(C语言)
好的,以下是用C语言编写输出关键路径的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTEX_NUM 20
#define INFINITY 65535
typedef struct {
int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵
int indegree[MAX_VERTEX_NUM]; // 入度
int ve[MAX_VERTEX_NUM]; // 事件最早发生时间
int vl[MAX_VERTEX_NUM]; // 事件最迟发生时间
int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 路径
int vertex_num; // 顶点数
int arc_num; // 弧数
} Graph;
typedef struct {
int data[MAX_VERTEX_NUM];
int top;
} Stack;
// 初始化栈
void InitStack(Stack *stack) {
stack->top = -1;
}
// 判断栈是否为空
bool StackIsEmpty(Stack *stack) {
return stack->top == -1;
}
// 判断栈是否已满
bool StackIsFull(Stack *stack) {
return stack->top == MAX_VERTEX_NUM - 1;
}
// 入栈
void Push(Stack *stack, int data) {
if (StackIsFull(stack)) {
printf("Stack is full.\n");
exit(1);
}
stack->data[++stack->top] = data;
}
// 出栈
int Pop(Stack *stack) {
if (StackIsEmpty(stack)) {
printf("Stack is empty.\n");
exit(1);
}
return stack->data[stack->top--];
}
// 拓扑排序
bool TopologicalSort(Graph *graph, Stack *stack) {
int i, j, k, count = 0;
InitStack(stack);
for (i = 0; i < graph->vertex_num; i++) {
if (graph->indegree[i] == 0) {
Push(stack, i);
}
}
while (!StackIsEmpty(stack)) {
j = Pop(stack);
printf("%d ", j);
count++;
for (k = 0; k < graph->vertex_num; k++) {
if (graph->arc[j][k] != INFINITY) {
if (--graph->indegree[k] == 0) {
Push(stack, k);
}
if (graph->ve[j] + graph->arc[j][k] > graph->ve[k]) {
graph->ve[k] = graph->ve[j] + graph->arc[j][k];
}
}
}
}
if (count < graph->vertex_num) {
return false;
} else {
return true;
}
}
// 关键路径
void CriticalPath(Graph *graph) {
int i, j, k, e, l;
Stack stack;
bool result;
result = TopologicalSort(graph, &stack);
if (!result) {
printf("The graph has a circle.\n");
exit(1);
}
for (i = 0; i < graph->vertex_num; i++) {
graph->vl[i] = graph->ve[graph->vertex_num - 1];
}
while (!StackIsEmpty(&stack)) {
j = Pop(&stack);
for (k = 0; k < graph->vertex_num; k++) {
if (graph->arc[j][k] != INFINITY) {
if (graph->vl[k] - graph->arc[j][k] < graph->vl[j]) {
graph->vl[j] = graph->vl[k] - graph->arc[j][k];
}
}
}
}
for (i = 0; i < graph->vertex_num; i++) {
for (j = 0; j < graph->vertex_num; j++) {
graph->path[i][j] = -1;
}
}
for (i = 0; i < graph->vertex_num; i++) {
for (j = 0; j < graph->vertex_num; j++) {
if (graph->arc[i][j] != INFINITY) {
e = graph->ve[i];
l = graph->vl[j] - graph->arc[i][j];
if (e == l) {
printf("Criticalpath: <%d,%d> length: %d\n", i, j, graph->arc[i][j]);
}
}
}
}
}
int main() {
Graph graph;
int i, j, k, m, n, w;
printf("Please input the vertex number and the arc number: ");
scanf("%d %d", &graph.vertex_num, &graph.arc_num);
for (i = 0; i < graph.vertex_num; i++) {
for (j = 0; j < graph.vertex_num; j++) {
graph.arc[i][j] = INFINITY;
}
}
for (k = 0; k < graph.arc_num; k++) {
printf("Please input the start vertex, the next vertex and the weight: ");
scanf("%d %d %d", &m, &n, &w);
graph.arc[m][n] = w;
graph.indegree[n]++;
}
CriticalPath(&graph);
return 0;
}
```
这个程序通过邻接矩阵来存储有向图,使用拓扑排序来求出每个事件的最早发生时间和最晚发生时间,然后求出关键路径。其中,INFINITY 表示两个顶点之间没有连边。
阅读全文