数据结构 关键路径

题目描述

给定各工序的时间和先序工序,利用 PT 图的方法,求关键路径及各个工序允许延误的时间。

输入格式

第 1 行为工序的个数 n(1 <= n <= 100)。

第 2 到 1 + n 行包含由空格隔开的工序号 V(i) ,所需时间 t 和先序工序号 Vpre(i) (0 <= V(i) < n, 0 <= Vpre(i) < n)。

若无先序工序则先序工序处为空,若有多个先序工序则用逗号隔开。

输出格式

输出文件包含三部分内容:

关键路径的总用时,

关键路径的各项工序号(可能有多条关键路径),

各项工序允许延误的时间。

输入样例 1

13
0 2
1 6 0
2 3 0
3 2 1
4 4 2,3
5 3 3
6 8 3
7 4 3
8 2 6,7
9 3 6
10 8 7,4
11 5 9
12 6 10

输出样例 1

28
[0->1->3->4->10->12->end]
[0->1->3->7->10->12->end]
0
0
5
0
0
15
2
0
8
2
0
2
0

输入样例 2

100
0 20 38,91,78,92,37,85,44
1 13 91,69,48,51,93,44,67,0,87,55,41,40,99,81,77,76,54,7
2 22 38,43,31,66,92,60,85,44,87,59,41,99,76
3 14 75
4 23 38,31,69,30,78,95,29,85,93,21,0
5 8 43,75,69,78,11,29,72,50,64,93,0,55,96,41
6 12 43,3,69,78,29,85,45,22,55,40
7 18 91,27,48,67,0,87,45,52,99
8 18 91,92,95,11,27,60,13,67,4,52,55,96,76,7,1,47,39,34,61,88,71,63,25,90
9 22 38,43,30,48,51,50,64,22,40,81,2,32,84,19,25,73,65,8,74,15,28,17
10 5 75,91,48,60,50,85,93,21,55,96,76,54,7,6,39,19,89,57,94,8,86,62
11 6 3,66,30,92
12 9 75,69,37,11,27,29,85,13,67,0,40,54
13 7 43,91,3,92,37,27,60
14 23 69,78,95,29,72,4,53,52,81,77,20,63,56,16,86,46,10,82,28,33,36
15 21 43,75,91,31,66,37,11,27,72,50,21,22,4,52,5,7,12,18,61,19,98,73,56,90,42,74
16 13 43,78,11,27,60,50,64,67,4,52,40,99,79,12,2,47,84,19,89,71,73,24,90,94
17 8 3,50,64,44,67,0,45,22,53,59,81,77,39,24,56,42,86,10,82
18 14 75,91,66,30,78,95,45,52,41,81,76,54,1
19 15 43,75,91,92,27,50,93,13,21,4,55,77,7,39,18,70
20 5 66,92,48,50,13,44,59,5,40,81,7,6,12,19
21 23 38,78,48,29
22 16 38,91,3,78,95,48,29,67
23 7 3,66,69,30,60,50,85,21,45,22,52,55,96,59,41,77,79,54,1,6,12,70,61,20,24,42,10,82,9,58
24 15 66,30,51,72,67,52,5,54,7,6,12,2,47,34,70,19,20,25,98
25 13 91,3,69,78,92,48,51,72,55,59,40,6,47,32,34,70,20,83
26 11 75,31,80,11,60,50,67,52,59,81,79,76,1,47,70,19,71,83,63,90,16,86,10
27 16 91,31,95,37,11
28 13 75,91,3,30,95,48,50,13,21,22,53,55,96,81,76,2,47,39,70,88,89,63,57,90,62,74
29 12 38,78,95,37
30 7
31 9 3
32 8 38,91,66,37,48,29,72,44,4,52,99,7,47
33 9 48,50,64,41,40,99,76,1,12,98,57,16,42,86,74,26,15
34 6 75,3,80,50,67,45,53,40,99,7,2,47
35 14 91,66,51,60,44,4,53,96,41,77,6,2,47,84,88,63,24,42,86,62
36 24 31,69,11,48,51,50,64,85,21,45,4,41,77,79,54,12,8,86,82
37 12 69
38 6
39 24 38,91,3,78,95,80,27,50,93,13,67,21,45,5,40,81,77,76,12,97
40 16 91,3,30,37,27,67,21,87,45,96,5
41 19 38,75,92,27,51,85,44,45,22,96
42 14 3,69,30,92,95,37,72,50,93,44,87,53,96,40,32,34,88,24,90
43 12
44 6 75,91,66,92,29,72,93
45 11 75,91,92,80,93,67,87
46 21 31,69,78,95,80,27,53,55,59,6,97,32,70,88,89,71,20,98,24,90,94
47 22 38,43,75,91,31,29,64,44,67,0,55,5,77,79,76,6
48 20 38,43,3,66,69,95,27
49 11 78,95,27,51,85,93,21,0,87,41,40,76,7,1,6,2,25,98,24,94,42,74,36
50 9 75,3,78
51 7 38,3
52 17 43,75,80,37,48,51,93,44,0,45
53 14 75,3,78,29,4
54 16 92,80,27,51,29,72,52,59,40,77
55 12 31,37,11,27,0,22
56 14 38,92,80,37,48,51,72,13,44,22,40,76,12,47,32,70,61,88,98
57 15 38,43,75,3,30,78,95,80,37,48,60,67,21,96,41,5,81,7,2,47,61,20
58 23 43,66,69,92,95,11,51,72,85,13,21,22,52,5,40,54,2,34,98,56,94,46,10,26,49
59 20 3,78,27,60,85,44,45,4,55
60 16 3,69,78,11,72
61 20 75,91,3,30,78,60,85,52,97,2,47,39,18,70
62 9 43,37,13,45,55,96,5,81,54,1,2,19,20,94,16
63 9 66,80,11,48,51,21,0,87,96,41,40,76,12,97,2,84,70,71
64 7 95,37,48,29
65 11 3,78,92,11,48,13,59,5,81,77,76,1,6,97,2,39,61,88,89,20,25,73
66 23 75,3,31
67 21 38,78,92,51,29,64
68 6 38,37,51,60,93,13,44,21,45,96,59,5,76,54,39,19,73,56,42,10,82,9
69 23 91
70 21 43,37,51,29,0,22,99,79,12,34
71 11 38,43,72,60,93,44,67,22,4,41,40,81,76,12,47,32,18,61
72 21 66,51
73 10 66,95,37,11,48,64,44,67,0,87,22,53,96,40,77,1,97,39,70,88,20
74 19 43,75,31,66,30,78,95,11,51,64,93,44,87,41,40,70,88,24,90,8,62
75 19
76 6 38,3,69,92,51,60,93,21,53,52,96,77
77 18 29,64,45,59,41,99
78 9 91,3
79 9 38,66,30,92,80,93,67,21,4,53,96,41
80 6 92
81 18 43,66,78,92,37,11,27,72,60,93,22,4,5
82 16 43,69,92,80,48,0,4,55,5,7,6,97,71,63,57,65,8,42,86,74,46
83 7 43,78,95,72,44,21,87,59,5,99,7,12,2,34
84 23 92,11,51,4,53,55,40,76
85 18 75,27,64
86 8 43,3,31,66,11,27,60,67,0,22,81,6,84,70,88,24
87 12 30,80,11,51,29,72,50,64,13,44
88 7 3,30,93,13,44,21,0,45,22,4,40,77,54,1,6,39,70,61,19
89 13 38,69,78,92,80,27,72,85,13,44,45,96,41,40,77,54,6,70
90 15 75,95,80,67,0,52,96,59,40,81,79,1,6,32,70,83,98,73,57
91 5 75
92 10 78
93 17 91,95,37,27,51,29
94 6 38,3,66,78,95,27,48,29,13,44,87,4,55,96,99,79,12,89,56,90
95 10 92
96 24 38,43,91,30,78,95,51,72,67,21,87,4
97 7 75,30,78,37,11,51,72,50,93,21,0,55,41,99,81,79
98 11 43,3,31,66,80,52,96,12,2,47,18,84,61,19,89,63
99 7 43,91,66,80,11,27,50,85,44,67,21,0,53,96,59

 输出样例 2

497
[75->3->31->66->11->27->48->64->85->0->4->96->41->5->40->6->47->34->70->61->71->63->98->90->94->16->62->74->82->36->49->58->23->end]
0
18
12
0
0
0
0
52
10
28
52
0
12
54
18
28
0
28
18
16
16
22
40
0
6
24
52
0
39
33
58
0
39
28
0
86
0
12
81
12
0
0
33
75
22
53
20
0
0
0
112
65
79
34
12
39
1
16
0
28
54
0
0
0
0
65
0
40
29
12
0
0
40
14
0
0
12
12
9
27
105
28
0
58
69
0
39
49
14
27
0
12
9
22
0
9
0
28
0
24

题解

以节点 i 代表工序 i 完成后的状态,节点 n 和 n + 1 分别代表初始状态和完工状态。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

typedef pair<int, int> p;
const int maxn = 102;
int deg[maxn], rdeg[maxn], ve[maxn], vl[maxn];
vector<p> pre[maxn], nxt[maxn];
vector<vector<int>> paths;

void addEdge(int now, int prev, int t)
{
    nxt[prev].push_back(p(now, t));
    pre[now].push_back(p(prev, t));
    deg[now]++;
    rdeg[prev]++;
}

vector<string> split(const string& s, const string& sep)
{
    vector<string> res;
    string::size_type pos1, pos2;
    pos2 = s.find(sep);
    pos1 = 0;
    while (string::npos != pos2)
    {
        res.push_back(s.substr(pos1, pos2 - pos1));
        pos1 = pos2 + sep.size();
        pos2 = s.find(sep, pos1);
    }
    if (pos1 != s.length()) res.push_back(s.substr(pos1));
    return res;
}

void topsort(int n)
{
    queue<int> q;
    q.push(n);
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        for (p p_nxt : nxt[now])
        {
            ve[p_nxt.first] = max(ve[p_nxt.first], ve[now] + p_nxt.second);
            if (--deg[p_nxt.first] == 0) q.push(p_nxt.first);
        }
    }
}

void topsort_rev(int n)
{
    memset(vl, 0x3f, sizeof(vl));
    vl[n + 1] = 0;
    for (int i = 0; i < n; i++) vl[n + 1] = max(vl[n + 1], ve[i]);
    queue<int> q;
    q.push(n + 1);
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        for (p p_pre : pre[now])
        {
            vl[p_pre.first] = min(vl[p_pre.first], vl[now] - p_pre.second);
            if (--rdeg[p_pre.first] == 0) q.push(p_pre.first);
        }
    }
}

void dfs(int now, int n, int sum, vector<int> vec)
{
    if (now == n + 1 && sum == vl[n + 1])
    {
        paths.push_back(vec);
        return;
    }
    if (now != n) vec.push_back(now);
    for (p p_nxt : nxt[now])
        if (ve[p_nxt.first] == vl[p_nxt.first])
            dfs(p_nxt.first, n, sum + p_nxt.second, vec);
}

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int now, t;
        cin >> now >> t;
        if (getchar() == '\n')
        {
            addEdge(now, n, t);
            continue;
        }
        string str;
        cin >> str;
        vector<string> prevs = split(str, ",");
        for (string prev : prevs) addEdge(now, stoi(prev), t);
    }
    for (int i = 0; i < n; i++) if (!rdeg[i]) addEdge(n + 1, i, 0);
    topsort(n);
    topsort_rev(n);
    cout << vl[n + 1] << endl;
    dfs(n, n, 0, {});
    for (vector<int> path : paths)
    {
        cout << "[";
        for (int id : path) cout << id << "->";
        cout << "end]" << endl;
    }
    for (int i = 0; i < n; i++) cout << vl[i] - ve[i] << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35850147/article/details/105579907
今日推荐