求有向图的关键路径(C++代码)

对于给定的有向图,先进行拓扑处理,然后求出最长路径。


//寻找图的关键路径 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;

//最大边数,最大点数 
const int Max_M=100100;
const int Max_N=50100;

struct Graph
{
	int nodeNumber,Link[Max_N],number;
	struct node
	{
		int vertex,weight,next;
	}	edge[Max_M];
	void initGraph(int n=0)
	{
		number=n;
		nodeNumber=0;
		memset(Link,-1,sizeof(Link));
	}
	void addEdge(int vertex_x,int vertex_y,int weight)
	{
		edge[nodeNumber].vertex = vertex_y;
		edge[nodeNumber].weight = weight;
		edge[nodeNumber].next = Link[vertex_x];
		Link[vertex_x] = nodeNumber;
		nodeNumber++;
	}
	void eraseLink(int vertex)
	{
		Link[vertex] = -1;
	}
} ;

 
// 求图的拓扑序 
int topoOrder[Max_N],inDegree[Max_N];
bool topo(Graph &G, int *topoOrder)
{
	memset(inDe
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是实现关键路径算法的C++代码: ```c++ #include<iostream> #include<vector> #include<queue> #include<cstring> using namespace std; const int MAXN = 10005; // 最大节点数 vector<pair<int, int>> G[MAXN]; // 邻接表存图 int inDegree[MAXN]; // 入度数组 int earliest[MAXN]; // 记录最早开始时间 int latest[MAXN]; // 记录最晚开始时间 int duration[MAXN]; // 记录每个节点的持续时间 void topologicalSort(int n) { queue<int> q; memset(earliest, 0, sizeof(earliest)); // 初始化最早开始时间为0 for(int i=1; i<=n; i++) if(inDegree[i] == 0) // 将所有入度为0的节点入队 q.push(i); while(!q.empty()) { int u = q.front(); q.pop(); for(int i=0; i<G[u].size(); i++) { int v = G[u][i].first; int w = G[u][i].second; inDegree[v]--; // 将u -> v这条边删除 if(inDegree[v] == 0) // 如果入度为0,则入队 q.push(v); earliest[v] = max(earliest[v], earliest[u]+w); // 更新最早开始时间 } } } void criticalPath(int n) { topologicalSort(n); memset(latest, earliest[n], sizeof(latest)); // 初始化最晚开始时间为最早开始时间 for(int u=n; u>=1; u--) // 倒序遍历每个节点 for(int i=0; i<G[u].size(); i++) { int v = G[u][i].first; int w = G[u][i].second; latest[u] = min(latest[u], latest[v]-w); // 更新最晚开始时间 } for(int u=1; u<=n; u++) for(int i=0; i<G[u].size(); i++) { int v = G[u][i].first; int w = G[u][i].second; if(latest[v]-w == earliest[u]) // 如果u -> v是关键路径上的边,则输出 cout << u << " -> " << v << endl; } } int main() { int n, m; cin >> n >> m; for(int i=0; i<m; i++) { int u, v, w; cin >> u >> v >> w; G[u].push_back(make_pair(v, w)); // 添加一条有向边u -> v inDegree[v]++; // 节点v的入度加1 duration[u] = w; // 记录节点u的持续时间 } criticalPath(n); // 进行关键路径算法 return 0; } ``` 以上代码中,`G`是邻接表,`inDegree`是入度数组,`earliest`记录最早开始时间,`latest`记录最晚开始时间,`duration`记录每个节点的持续时间,`topologicalSort`函数实现了拓扑排序算法并计算最早开始时间,`criticalPath`函数实现了关键路径算法。在`main`函数中读入了节点数`n`和有向边数`m`,并将所有有向边添加到邻接表中,同时更新每个节点的入度和持续时间。最后调用`criticalPath`函数进行关键路径算法,输出关键路径上的边。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值