Topological Sort

编写一个程序,对有向图进行拓扑排序。程序应处理函数格式,并在存在环的情况下返回失败标志。输入样例保证了结果的唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Write a program to find the topological order in a digraph.

Format of functions:

bool TopSort( LGraph Graph, Vertex TopOrder[] );

where LGraph is defined as the following:

typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;
    PtrToAdjVNode Next;
};

typedef struct Vnode{
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;
    int Ne;
    AdjList G;
};
typedef PtrToGNode LGraph;

The topological order is supposed to be stored in TopOrder[] where TopOrder[i] is the i-th vertex in the resulting sequence. The topological sort cannot be successful if there is a cycle in the graph -- in that case TopSort must return false; otherwise return true.

Notice

好的,以下是用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 表示两个顶点之间没有连边。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值