关键路径问题的求解(邻接表+队列+栈)

因为没怎么找到一些关键路径的练习题,自己编了一个,学以致用

/*
描述如下:
我们保证只有一个源点和汇点;
第一行输入顶点数 n 和边数 m  
下列m行为起点到目标顶点编号以及距离(从1开始编号!想要fill的注意了(终点必须是arr+n+1,起点无所谓了)) 
7 8
1 2 1
1 3 2
2 4 3
3 4 3
4 5 2
4 6 1
5 7 3
6 7 3
*/
#include <bits/stdc++.h>

using namespace std;

const int MAXN=1001;
const int INF=INT_MAX;

struct Edge{
	int to;
	int length;
	Edge(int t,int l):to(t),length(l){}
};

vector<Edge>graph[MAXN];
int earliest[MAXN];//和拓扑排序相比,多加了两个数组 ;正向找最大值的earliest(咱们最迟啥时候做这件事) 
int latest[MAXN];//和拓扑排序相比,多加了两个数组 :逆向到最小值的latest 
int inDegree[MAXN];

void Criticalpath(int n)
{
	queue<int>myqueue; 
	stack<int>mystack;
	for(int i=1;i<=n;i++)
	{
		if(inDegree[i]==0) myqueue.push(i);
	}
	while(!myqueue.empty())
	{
		int u=myqueue.front();
		myqueue.pop();
		mystack.push(u);
		for(int i=0;i<graph[u].size();i++)
		{
			int v=graph[u][i].to;
			int l=graph[u][i].length;
			inDegree[v]--;
			earliest[v]=max(earliest[v],earliest[u]+l);//正序找最大的
			if(inDegree[v]==0) myqueue.push(v);
		}
	}
	while(!mystack.empty())
	{
		int u=mystack.top();
		mystack.pop();
		if(graph[u].size()==0) 
		{
			latest[u]=earliest[u];
		}
		for(int i=0;i<graph[u].size();i++)
		{
			int v=graph[u][i].to;
			int l=graph[u][i].length;
			latest[u]=min(latest[u],latest[v]-l);//逆序找最小的
		}
	}
	return ;
}

int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(graph,0,sizeof(graph));
		memset(earliest,0,sizeof(earliest));
		fill(latest,latest+n+1,INF);
		memset(inDegree,0,sizeof(inDegree));
		while(m--)
		{
			int from,to,length;
			scanf("%d%d%d",&from,&to,&length);
			graph[from].push_back(Edge(to,length));
			inDegree[to]++;	
		}
		Criticalpath(n);
		int answer=0;
		for(int i=1;i<=n;++i)//++i的效率高的呀! 
		{
			if(latest[i]==earliest[i]) 
			{
				answer=max(answer,earliest[i]);
				cout<<"关键路径的节点为:"<<i<<endl; 
			} 
		}	
		printf("关键路径总长度为:%d\n",answer);
	}
	return 0;	
} 

发布了8 篇原创文章 · 获赞 0 · 访问量 66

猜你喜欢

转载自blog.csdn.net/weixin_46274692/article/details/105053171