关键路径
数据结构课程-关键路径
拓扑排序 判环 + bfs(栈实现)
#include <bits/stdc++.h>
using namespace std;
inline void _A_A_();
signed main() {_A_A_();return 0;}
const int maxn = 1e3 + 10;
struct edge {
int to, nxt, w;
}e[maxn * 4];
int idx,h[maxn];
void add(int u,int v, int w) {
e[idx].to = v;
e[idx].w = w;
e[idx].nxt = h[u];
h[u] = idx++;
}
int n, m;
vector<int> topo; // 拓扑序
vector<int> ve(maxn, 0), vl(maxn,0), in(maxn, 0), vis(maxn, 0); // 不建议
int ve[5000], vl[5000], in[5000], vis[5000]; // 建议
bool TopoSort() {
stack<int> stk;
for (int i = 0;i < n;i++) {
if (in[i] == 0) {
vis[i] = 1;
stk.push(i);
}
}
while (!stk.empty()) {
int u = stk.top();
stk.pop();
topo.push_back(u);
for (int i = h[u];~i;i=e[i].nxt) {
in[e[i].to]--;
if (in[e[i].to] == 0) {
vis[e[i].to] = 1;
stk.push(e[i].to);
}
}
}
for (int i = 0;i < n;i++) {
if (!vis[i]) {
return 0;
}
}
return 1;
}
拓扑排序 判环 + dfs
注意:dfs得到的topo
是拓扑逆序
#include <bits/stdc++.h>
using namespace std;
inline void _A_A_();
signed main() {_A_A_();return 0;}
struct edge {
int from, to, nxt, w;
}e[5000];
int idx,h[5000];
void add(int u,int v, int w) {
e[idx].to = v;
e[idx].w = w;
e[idx].nxt = h[u];
h[u] = idx++;
}
int n, m;
vector<int> topo; // 拓扑序
int ve[5000], vl[5000], in[5000], vis[5000];
bool dfs(int u) {
vis[u] = 1;
for (int i = h[u];i != -1;i=e[i].nxt) {
if (vis[e[i].to] == 1) return 1;
if (vis[e[i].to] == 0 && dfs(e[i].to)) return 1;
}
vis[u] = -1;
topo.push_back(u);
return 0;
}
bool TopoSort() {
for (int i = 0;i < n;i++) {
if (vis[i] == 0 && dfs(i) ) {
return 0;
}
}
return 1;
}
关键路径
包含:
- ve与vl
- ee与el
- 关键路径
#include <bits/stdc++.h>
using namespace std;
inline void _A_A_();
signed main() {_A_A_();return 0;}
struct edge {
int from, to, nxt, w;
}e[5000];
int idx,h[5000];
void add(int u,int v, int w) {
e[idx].from = u;
e[idx].to = v;
e[idx].w = w;
e[idx].nxt = h[u];
h[u] = idx++;
}
int n, m;
vector<int> topo; // 拓扑序
int ve[5000], vl[5000], in[5000], vis[5000];
bool dfs(int u) {
vis[u] = 1;
for (int i = h[u];i != -1;i=e[i].nxt) {
if (vis[e[i].to] == 1) return 1;
if (vis[e[i].to] == 0 && dfs(e[i].to)) return 1;
}
vis[u] = -1;
topo.push_back(u);
return 0;
}
bool TopoSort() {
for (int i = 0;i < n;i++) {
if (vis[i] == 0 && dfs(i) ) {
return 0;
}
}
return 1;
}
void GJLJ() {
assert(TopoSort());
// 按拓扑序 求ve
for (int i = n - 1;i >= 0;i -- ) {
int u = topo[i];
for (int j= h[u];j != -1;j=e[j].nxt) {
ve[e[j].to] = max(ve[e[j].to], ve[u] + e[j].w);
}
}
// 按逆拓扑序 求vl
for (int i = 0;i < n;i++) vl[i] = ve[topo[0]];
for (int i = 0;i < n;i++) {
int u = topo[i];
for (int j = h[u];~j;j=e[j].nxt) {
vl[u] = min(vl[u], vl[e[j].to] - e[j].w);
}
}
// 易知ee[i]就是边e[i].from的ve
for (int i = 0;i < idx;i++) {
cout << ve[e[i].from] << "\n";
}
// 易知el[i]就是边e[i].to的vl 再减掉e[i].w
for (int i = 0;i < idx;i++) {
cout << vl[e[i].to] - e[i].w << "\n";
}
// 关键路径 ee[i] == el[i]
for (int i = 0;i < idx;i++) {
if (ve[e[i].from] == (vl[e[i].to] - e[i].w))
cout << e[i].from << "-->" << e[i].to << ":" << ve[e[i].from] << "\n";
}
}
inline void _A_A_() {
memset(h,-1,sizeof h);
cin >> n >> m;
for (int i = 0;i < m;i++) {
int aa, bb, cc;
cin >> aa >> bb >> cc;
add(aa,bb,cc);
in[bb]++;
}
GJLJ();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App