关键路径criticalpath(邻接矩阵建图+bfs)

本文深入探讨了关键路径算法,一种用于项目管理的重要技术。通过详细解释算法步骤,包括图的初始化、拓扑排序和关键路径识别,文章展示了如何确定项目中最长的依赖路径,从而估算项目的最短完成时间。此外,还提供了C++实现代码,帮助读者理解并应用这一算法。

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

# include<iostream>
# include<queue>
# include<cstring>
# include<stack> 
# define inf 0x3f3f3f3f
using namespace std;
const int maxn=50;
typedef struct node{
	int adj;      //顶点之间的权重 
}node;
typedef struct graph{
	int vertex[maxn];
    node vertexs[maxn][maxn];//邻接矩阵 
    int vertexnum;
    int edgenum;
}graph;
int indegree[maxn];
queue<int> q;
stack<int> ss;
int ve[maxn];//事件最早发生时间
int vl[maxn];//事件最迟发生事件
int e[maxn];//活动最早开始时间
int l[maxn];//活动最迟开始时间
int find(graph g,int i)  //寻找对应顶点的索引 
{
	for(int j=0;j<g.vertexnum;j++)
	    if(g.vertex[j]==i)
	      return j;
	return -1;
}
void init(graph &g)   //初始化图 
{
	cin>>g.vertexnum>>g.edgenum;
	for(int i=0;i<g.vertexnum;i++)
	  cin>>g.vertex[i];
	for(int i=0;i<g.vertexnum;i++)
	  for(int j=0;j<g.vertexnum;j++)
	      g.vertexs[i][j].adj=inf;
	for(int i=0;i<g.edgenum;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
	    int index_u=find(g,u);
		int index_v=find(g,v);
		g.vertexs[index_u][index_v].adj=w;   	
	  }
	  
}
void findindegree(graph g,int indegree[])
{
	for(int i=0;i<g.vertexnum;i++)
	{
		for(int j=0;j<g.vertexnum;j++)
		{
			if(i!=j&&g.vertexs[j][i].adj!=inf)  //有j到i的边 ,就让i的入度加1; 
			   indegree[i]++;
		}
	}
}
bool topulogicalsort(graph g)
{
	int cnt=0;
	for(int i=0;i<g.vertexnum;i++)  //入度为0的顶点进队列 
	{
		 if(!indegree[i])
	     q.push(i);
	   ve[i]=0;  
	  } 
	while(!q.empty())
	{
		int k=q.front();
		q.pop();
		ss.push(k);
		cnt++;
		for(int i=0;i<g.vertexnum;i++)
		{
			int w=g.vertexs[k][i].adj;
		   if(w!=inf)   //表示相邻 
		    {
		    	indegree[i]--;
		    	if(!indegree[i])
		    	  q.push(i);
		        if(ve[k]+w>ve[i])  
				   ve[i]=ve[k]+w;	  
			  }  
		        
		  }
	}
	if(cnt<g.vertexnum) return false;
	return true;
}
void criticalpath(graph g)
{
	if(!topulogicalsort(g))
	{
		cout<<"存在回路"<<endl;
		return ;
	}
	for(int i=0;i<g.vertexnum;i++)  //初始化事件最迟开始时间 
	   vl[i]=ve[g.vertexnum-1];
	while(!ss.empty())
	{
		int k=ss.top();
		ss.pop();
		for(int i=0;i<g.vertexnum;i++)
		{
			int w=g.vertexs[k][i].adj;
			if(w!=inf)
			{
				if(vl[k]>vl[i]-w)
				   vl[k]=vl[i]-w;
			}
		}
	}
	for(int i=0;i<g.vertexnum;i++)
	{
	  for(int j=0;j<g.vertexnum;j++)
	  {
	  	int w=g.vertexs[i][j].adj;
	  	if(w!=inf)
	  	{
	  		int ee=ve[i];
	  		int el=vl[j]-w;
	  		if(ee==el)
	  		{
	  			cout<<"V"<<g.vertex[i]<<"->"<<"V"<<g.vertex[j]<<" dis"<<w<<endl;
			  }
	  		
		  	}
	  	
	  	
	   }	
	 	
	 }
	
	
}
int main()
{
	graph g;
	init(g);
	memset(indegree,0,sizeof(indegree));
	findindegree(g,indegree);
	criticalpath(g);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值