算法导论 · 动态规划 · DAG最长路径

  • 算法说明
    先对图进行拓扑排序,再从入度的节点开始计算
    dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)}
  • 源代码
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

#define maxn 100 + 1
#define maxDilg(a, b) (a) > (b) ? (a) : (b)

struct node {
	int v, w;
	node(int vv, int ww) {
		v = vv;
		w = ww;
	}
};

vector<node> vt[maxn];
int n, m, indegree[maxn], s[maxn], dilg[maxn];
int a, b, c;

bool topologicalSort();

int main() {
	memset(indegree, 0, sizeof(indegree));
	memset(dilg, 0, sizeof(dilg));
	freopen("4.longestPathInDAG.txt", "r", stdin);
	//freopen("4.longestPathInDAGOutput.txt", "w", stdout);
	
	scanf("%d%d", &n, &m);
	while(m--) {
		scanf("%d%d%d", &a, &b, &c);
		vt[a].push_back(node(b, c));
		indegree[b]++;
	}
	
//	int t = 5;
//	printf("(%d, %d, %d)", t, vt[t][0].v, vt[t][0].w); //测试图是否成功创建
 
//	printf("%d\n", topologicalSort()); //测试拓扑排序 
	topologicalSort();
	
//	for(int i = 0; i < n; i++) { //打印拓扑排序后节点 
//		printf("%d ", s[i]);
//	}

	for(int i = 0; i < n; i++) {
		int t = s[i];
		for(int j = 0; j < vt[t].size(); j++) {
			int v = vt[t][j].v;
			dilg[v] = maxDilg(dilg[v], dilg[t] + vt[t][j].w);
		}
	} 
	
	printf("%d ", dilg[s[n - 1]]);
	return 0;
}

bool topologicalSort() {
	int num = 0; //记录加入排序的顶点数 
	queue<int> q;
	
	for(int i = 1; i <= n; i++) { //将入度为0的顶点加入队列 
		if(indegree[i] == 0) {
			q.push(i);
		}
	}
	
	while(!q.empty()) {
		int u = q.front();
		s[num++] = u;
		q.pop();
		
		for(int i = 0; i < vt[u].size(); i++) { //对其所有后续节点进行判断 
			int v = vt[u][i].v; 
			indegree[v]--;
			if(indegree[v] == 0) {
				q.push(v);
			}
		}
	}
	
	if(num == n) return true; //是有向无换图,且拓扑排序完成 
	else return false;
}
  • 数据输入
    在这里插入图片描述
  • 运行结果
    在这里插入图片描述
发布了77 篇原创文章 · 获赞 40 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/y_dd6011/article/details/97433516