关键路径(DAG最长路练习)

题目描述

    一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图。
    AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG。与AOV不同,活动都表示在了边上,如下图所示:
                                     
    如上所示,共有11项活动(11条边),9个事件(9个顶点)。整个工程只有一个开始点和一个完成点。即只有一个入度为零的点(源点)和只有一个出度为零的点(汇点)。
    关键路径:是从开始点到完成点的最长路径的长度。路径的长度是边上活动耗费的时间。如上图所示,1 到2 到 5到7到9是关键路径(关键路径不止一条,请输出字典序最小的),权值的和为18。

输入

    这里有多组数据,保证不超过10组,保证只有一个源点和汇点。输入一个顶点数n(2<=n<=10000),边数m(1<=m <=50000),接下来m行,输入起点sv,终点ev,权值w(1<=sv,ev<=n,sv != ev,1<=w <=20)。数据保证图连通。

输出

    关键路径的权值和,并且从源点输出关键路径上的路径(如果有多条,请输出字典序最小的)。

示例输入

9 11
1 2 6
1 3 4
1 4 5
2 5 1

题目描述

    一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图。
    AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG。与AOV不同,活动都表示在了边上,如下图所示:
                                     
    如上所示,共有11项活动(11条边),9个事件(9个顶点)。整个工程只有一个开始点和一个完成点。即只有一个入度为零的点(源点)和只有一个出度为零的点(汇点)。
    关键路径:是从开始点到完成点的最长路径的长度。路径的长度是边上活动耗费的时间。如上图所示,1 到2 到 5到7到9是关键路径(关键路径不止一条,请输出字典序最小的),权值的和为18。

输入

    这里有多组数据,保证不超过10组,保证只有一个源点和汇点。输入一个顶点数n(2<=n<=10000),边数m(1<=m <=50000),接下来m行,输入起点sv,终点ev,权值w(1<=sv,ev<=n,sv != ev,1<=w <=20)。数据保证图连通。

输出

    关键路径的权值和,并且从源点输出关键路径上的路径(如果有多条,请输出字典序最小的)。

示例输入

9 11
1 2 6
1 3 4
1 4 5
2 5 1
3 5 1
4 6 2
5 7 9
5 8 7
6 8 4
8 9 4
7 9 2

/******************************
author:yomi
date:18.9.7
ps: 考前突袭 原理没太搞懂啦 晴神的模板真真好用 不理解含义怕是不保险 木事木事 等我三刷 定要把那PAT拿下
******************************/
#include<iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 5010;
int dp[maxn], choice[maxn];
const int INF = 0x3fffffff;
int g[maxn][maxn];
int n, m;
int DP(int i)
{
    if(dp[i] > 0) return dp[i];
    for(int j=1; j<=n; j++){
        if(g[i][j]!=INF){
            int temp = g[i][j]+DP(j);
            if(temp > dp[i]){
                dp[i] = temp;
                choice[i] = j;
            }
        }

    }
    return dp[i];
}
void print(int i)
{
    printf("%d ", i);
    while(choice[i]!=-1){
        i = choice[i];
        printf("%d ", i);
    }
}
int main()
{
    fill(g[0], g[0]+maxn*maxn, INF);
    fill(choice, choice+maxn, -1);
    cin >> n >> m;
    int u, v, w;
    for(int i=0; i<m; i++){
        cin >> u >> v >> w;
        g[u][v] =  w;
    }
    for(int i=1; i<=n; i++){
        DP(i);
    }
    int Max = 0, j = -1;
    for(int i=1; i<=n; i++){
        if(dp[i] > Max){
            Max = dp[i];
            j = i;
        }
    }
    if(j!=-1){
        cout << dp[j] << endl;
        print(j);

    }
    return 0;
}
/**
9 11
1 2 6
1 3 4
1 4 5
2 5 1
3 5 1
4 6 2
5 7 9
5 8 7
6 8 4
8 9 4
7 9 2
**/
原文地址:https://www.cnblogs.com/AbsolutelyPerfect/p/9607033.html