最近在准备复试,虽然关键路径机试从没考过,以防万一,自己实现一下。理论书上基本都有,就不写了。
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
const int maxn = 1000;
struct node {
int v;
int w;
};
vector<node>graph[maxn];
int n, m;
int inDegree[maxn],ve[maxn],vl[maxn];
stack<int>topoSort;
vector<node>critPath[maxn];
vector<int>temp;
void topo() {
int pos = -1;
queue<int>q;
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) {
pos = i;
break;
}
}
q.push(pos);
while (!q.empty()) {
pos = q.front();
q.pop();
topoSort.push(pos);
for (int i = 0; i < graph[pos].size(); i++) {
int v = graph[pos][i].v;
inDegree[v]--;
if (inDegree[v] == 0)q.push(v);
if (ve[v] < ve[pos] + graph[pos][i].w) {
ve[v] = ve[pos] + graph[pos][i].w;
}
}
}
}
int critical_path() {
int maxL = 0, end = 0;
for (int i = 0; i < n; i++) {
if (ve[i] > maxL) {
maxL = ve[i];
end = i;
}
}
cout << "length: " << maxL << endl;
fill(vl, vl + n, maxL);
while (!topoSort.empty()) {
int pos = topoSort.top();
topoSort.pop();
for (int i = 0; i < graph[pos].size(); i++) {
int v = graph[pos][i].v;
if (vl[v] - graph[pos][i].w < vl[pos]) {
vl[pos] = vl[v] - graph[pos][i].w;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < graph[i].size(); j++) {
int v = graph[i][j].v, w = graph[i][j].w;
int e = ve[i], l = vl[v] - w;
if (e == l) {
cout << i << " " << v << endl;
critPath[i].push_back({ v,graph[i][j].w });
}
}
}
return end;
}
void dfs(int start,int end) {
temp.push_back(start);
if (start == end) {
for (int i = 0; i < temp.size(); i++) {
cout << temp[i];
if (i != temp.size() - 1)cout << " ";
else
cout << endl;
}
return;
}
for (int j = 0; j < critPath[start].size(); j++) {
int v = critPath[start][j].v;
dfs(v, end);
temp.pop_back();
}
}
int main() {
cin >> n >> m;
fill(inDegree, inDegree + n, 0);
fill(ve, ve + n, 0);
for (int i = 0; i < m; i++) {
int s, e, l;
cin >> s >> e >> l;
graph[s].push_back({ e,l });
inDegree[e]++;
}
topo();
cout << "关键活动:" << endl;
int end = critical_path();
cout << "关键路径:" << endl;
dfs(0, end);
return 0;
}