关键路径
问题:
一项工程有n个小项目要完成,一些项目的开始建立在一些项目的完成的基础上。求哪些项目是关键项目?
(关键项目:提前该项目可以缩短工程时间)
关键项目求解:
》对邻接表进行拓扑排序。
》按拓扑排序的顺序求每个项目完成的最早时间。
》按逆拓扑序列求每个项目完成的最迟时间。
》其中 最迟时间==最早时间 的项目就是 ‘关键项目’。
#include <stack> #include <memory> #include <iostream> #include <cstring> #include <cstdio> using namespace std; #define MAX 1000//定义图结点的最大个数 int n, m; //n代表顶点数,m代表边数 int ve[MAX], vl[MAX]; //记录事件的最早发生,最迟发生时间 typedef struct arc_data //边信息 { int time; int vex; //邻接的结点在数组中的编号 struct arc_data *next; } arc_data; struct Node //顶点信息 { arc_data *head; } adj[MAX]; bool v[MAX]= {false}; int in_count[MAX]; //记录结点入度数的数组 int topo[MAX]; //保存拓扑排序结果 void create( ) //生成图(邻接表实现) { int i; memset(in_count, 0, sizeof(int)*(n+1)); //入度数组清零 for(i=1; i<=n; ++i) //初始化表头结点 adj[i].head = NULL; for(i=0; i<m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); in_count[b]++; // 记录入度值 arc_data *q; q = new arc_data; q->time=c; q->vex = b; q->next= adj[a].head; //新边插入邻接表~~ adj[a].head = q; } } bool topo_sort() //邻接表拓扑排序 { stack<int> S; arc_data *p ; int showNum=0, k=1; //记录输出的结点的数目 for(int i=1; i<=n; ++i)//在in_count数组中找出入度为0的结点,并分别入栈 if(in_count[i]==0) S.push(i); //入度为0的全入栈 while(!S.empty()) { int v=S.top(); S.pop(); topo[k++]=v; //记录拓扑排序结果 in_count[v]=-1; //将该点入度调为-1 ++showNum; p=adj[v].head; while(p!=NULL) //遍历以v为起点所临接的点 { --in_count[p->vex]; //结点入度数减1 if(in_count[p->vex]==0) //入度数为0时入栈 S.push(p->vex); p=p->next; } } if(showNum<n) return 0; //存在环 return 1; } bool import_path(){ if(!topo_sort()) return 0; /**** 获取最早发生时间 ****/ memset(ve, 0, sizeof(ve)); // 将每个时间最早发生时间初始为0 for(int i=1; i<=n; i++){ int k=topo[i]; //拓扑排序第一个序号开始 arc_data *p = adj[k].head; //p指向第一个邻接顶点 while(p!=NULL){ //更新k的关联的顶点的最早发生时间 int j=p->vex; //j为邻接点信号 if(ve[j] < ve[k]+p->time) //跟新j的最早发生时间 ve[j]=ve[k]+p->time; p = p->next; } } /**** 最迟发生时间 ****/ for(int i=1; i<=n; i++) //将每个事件最迟发生时间ve[n] vl[i]=ve[n]; for(int i=n; i>0; i--){ int k=topo[i]; arc_data *p=adj[k].head; while(p!=NULL){ int j=p->vex; if(vl[k] > vl[j]-p->time){
vl[k]=vl[j]-p->time; }
p=p->next; } } return 1; } void print(){ /**** 判断每个事件是不是关键事件 ****/ for(int i=1; i<=n; i++){ int k=topo[i]; arc_data *p=adj[k].head; while(p!=NULL){ int j=p->vex; if(ve[k] == (vl[j]-p->time) ){
printf("%d->%d是关键路径\n", k, j);
} p=p->next; } } return ; } int main(){ while(scanf("%d%d", &n, &m)!=EOF){ create(); if(import_path()){
print(); }
} return 0; }

浙公网安备 33010602011771号