关键路径



#include "stdio.h"
#include "string.h"

#define VERTEX_NUMBER (30+3) //顶点的最大数量

int matrix[VERTEX_NUMBER][VERTEX_NUMBER];//邻接矩阵

int indegree[VERTEX_NUMBER];//各个顶点的入度

int stack[VERTEX_NUMBER];//栈

int stack2[VERTEX_NUMBER];//栈

int ve[VERTEX_NUMBER];//事件最早发生时间

int vl[VERTEX_NUMBER];//事件最迟发生时间
void print_array (int *,int);
void print_matrix (int (*)[VERTEX_NUMBER],int,int);
//关键路径
int critical_path (int n) {
		int i,j = 0,k = 0;
		int count = 0;
		int ee,el;
		for (i = 1;i <= n;i++) {
				if (0 == indegree[i]) {
						stack[j++] = i;	
				}
		}
		memset(ve,0,sizeof(ve));
		//求事件的最早发生时间(保存在ve中)和拓扑逆序列(保存在栈stack2中)
		while (j > 0) {
				int t = stack[--j];
				count++;
				stack2[k++] = t;	
				for (i = 1;i <= n;i++) {
						if (matrix[t][i] > 0){
								if (0 == --indegree[i]) {//入度减少为0,入栈
										stack[j++] = i;	
								}
								if (ve[t] + matrix[t][i] > ve[i]) {
										ve[i] = ve[t] + matrix[t][i];
								}
						}
				}
		}
		if (count < n) {//有向图中存在环
				return 0;
		}
		//默认源点为1,汇点为n
		for (i = 1;i <= n;i++) {
				vl[i] = ve[n];
		}
		//求事件的最迟发生时间
		while (k > 0) {
				int t = stack2[--k];
				for (i = 1;i <= n;i++) {
						if (matrix[i][t] > 0) {
								if (vl[t] - matrix[i][t] < vl[i]) {
										vl[i] = vl[t] - matrix[i][t];
								}
						}
				}
		}
		print_array (ve,n);
		print_array (vl,n);
		//求关键路径
		for (i = 1;i <= n;i++) {
			for (j = 1;j <= n;j++) {
				if (matrix[i][j] > 0) {
					ee = ve[i];
					el = vl[j] - matrix[i][j];
					if (ee == el) {
						printf ("<%d,%d> %d\n",i,j,matrix[i][j]);
					}
				}
			}
		}
		return 1;
}





int main () {
		int n,m,w;//n为顶点的数量,m为弧的个数,w为弧的权值
		int i;
		int v,u;
		scanf ("%d%d",&n,&m);
		memset (matrix,0,sizeof (matrix));
		memset (indegree,0,sizeof(indegree));
		for (i = 1;i <= m;i++) {
				scanf ("%d%d%d",&v,&u,&w);
				matrix[v][u] = w;
				indegree[u]++;
		}
		
		print_matrix (matrix,n,n);
		critical_path (n);
		return 0;
}

void print_array (int * t,int n) {
		int i;
		for (i = 1;i <= n;i++) {
				printf ("%d ",t[i]);
		}
		printf ("\n");
}
void print_matrix (int (*t)[VERTEX_NUMBER],int row,int line){
		int i,j;
		for (i = 1;i <= row;i++){
				print_array (t[i],line);
		}
		printf ("\n");
}

input:
9 11
1 2 6
1 3 4
2 5 1
3 5 1
5 7 8
5 8 7
7 9 2
8 9 4
1 4 5
4 6 2
6 8 4

output:

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 8 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 

0 6 4 5 7 7 15 14 18 
0 6 6 8 7 10 16 14 18 

<1,2> 6
<2,5> 1
<5,8> 7
<8,9> 4



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值