Topological Sort

原理:1:在有向图中选一个入度为零的顶点并输出。2:从图中删除该顶点和所有以它为尾的弧
重复上面二个步骤,直至全部的顶点都输出或者当前图中不存在入度为零的顶点为止,否则说明图中存在环。
#include "stdio.h" 
#include "string.h"
#define VERTEX_NUM 30
int matrix[VERTEX_NUM][VERTEX_NUM];//邻接矩阵
int indegree[VERTEX_NUM];//记录每个顶点的入度
int topological_sort (int n) {//n顶点的个数
		int stack[VERTEX_NUM];
		int front = 0;
		int i;
		int count = 0;
		for (i = 0;i < n;i++) {
				if (indegree[i] == 0) {
						stack[front++] = i;//入度为0的顶点进栈
				}
		}
		while (0 != front) {
				int v = stack[--front];
				count++;
				printf ("%d ",v+1);
				for (i = 0;i < n;i++) {
						if (1 == matrix[v][i]) {
								indegree[i]--;
								if (0 == indegree[i]) {
										stack[front++] = i;
								}
						}
				}
		}
		if (count < n) {
				return -1;//存在环
		}else {
				return 1;
		}
}
int main () {
		int n;//顶点数
		int m;//边数
		int i;
		memset (matrix,0,sizeof(matrix));
		memset (indegree,0,sizeof(indegree));
		scanf ("%d%d",&n,&m);
		for (i = 0;i < m;i++) {
				int v,u;
				scanf ("%d%d",&v,&u);
				if (matrix[v-1][u-1] == 0) {
						indegree[u-1]++;
				}
				matrix[v-1][u-1] = 1;
		}
		i = topological_sort (n);
		if (i == 1) {
				printf ("YES");
		}else {
				printf ("NO");
		}
		return 0;
}


在无环的有向图中可以使用深度优先遍历进行拓扑排序。按照退出DFS函数的先后记录下来顶点的序列,即为逆向的拓扑有序序列。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是用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、付费专栏及课程。

余额充值