Codeup 问题 A: 关键路径

    科技2022-07-12  123

    原题地址

    http://codeup.hustoj.com/problem.php?cid=100000624&pid=0

    解题思路

    本来套了一下模板,然后一直是答案错误。 参考本篇博文: https://blog.csdn.net/qq_33375598/article/details/104439436 发现似乎是要加一步,即确定源点是哪一个。 方法即为遍历ve数组,ve[i]=0时i即为源点。 所以不能再判断e是否等于l之后直接输出关键路径,而应另外开一个数组存储路径~ 参考代码有借鉴上面那篇博文的部分qwq

    参考代码

    #include <bits/stdc++.h> using namespace std; #define pb push_back const int maxn = 30; struct node{ int v, w; }; int x; //x顶点个数 int inDegree[maxn], ve[maxn], vl[maxn]; vector<node> G[maxn]; //求解关键路径 stack<int> topOrder; vector<int> ans[maxn]; //关键路径 bool tpSortPath() { queue<int> q; int num = 0; for (int i = 0; i < x; i++) { if (!inDegree[i]) q.push(i); } while (!q.empty()) { int v = q.front(); q.pop(); num++; topOrder.push(v); for (int i = 0; i < G[v].size(); i++) { int w = G[v][i].w; int v1 = G[v][i].v; if (--inDegree[v1] == 0) q.push(v1); if (ve[v] + w > ve[v1]) { ve[v1] = ve[v] + w; } } } if (num == x) return true; else return false; } int criticalPath() { fill(ve, ve + maxn, 0); if (!tpSortPath()) return -1; /*不确定汇点时,找最长的*/ int maxLength = 0; for (int i = 0; i < x; i++) { if (ve[i] > maxLength) maxLength = ve[i]; } fill(vl, vl + maxn, maxLength); int u, v, w; while (!topOrder.empty()) { u = topOrder.top(); topOrder.pop(); for (int i = 0; i < G[u].size(); i++) { v = G[u][i].v; w = G[u][i].w; if (vl[v] - w < vl[u]) { vl[u] = vl[v] - w; } } } vector<int> ans[maxn]; for (int u = 0; u < x; u++) { for (int i = 0; i < G[u].size(); i++) { v = G[u][i].v; w = G[u][i].w; int e = ve[u]; int l = vl[v] - w; //if (e == l) printf("(%c,%c) ", u + 'a', v + 'a'); if (e == l) ans[u].pb(v); } } /*要找源点!!*/ int s; //源点 for (int i = 0; i < x; i++) { if (ve[i] == 0) { s = i; //找到源点 break; } } while (ans[s].size()) { //没有后继结点时退出 printf("(%c,%c) ", s + 'a', ans[s][0] + 'a'); s = ans[s][0]; } return maxLength; } int main() { int n, y, w; char a, b; string nu; cin >> n; while (n--) { //初始化 scanf("%d%d", &x, &y); char str[maxn]; scanf("%s", str); for (int i = 0; i < maxn; i++) G[i].clear(); fill(inDegree, inDegree + maxn, 0); //getchar(); //getline(cin, nu); //cout << nu << endl; while (y--) { scanf("%*c%c %c %d", &a, &b, &w); //这里也是参考写的输入方式 //%*c意思是读入一个字符但是忽略它 //cout << a << b << w << endl; int v1 = a - 'a'; //求得结点的值 int v2 = b - 'a'; G[v1].pb(node{v2, w}); inDegree[v2]++; } int ans = criticalPath(); printf("%d\n", ans); } }
    Processed: 0.013, SQL: 8