C++ 关键路径

代码实现

#include <iostream>
#include <cstdio>
#include <stack>
#include <string>
#include <windows.h>
using namespace std;
int vertex_num;
int edge_num;
struct Edge
{
    int edge_from;  // 顶点1
    int edge_to;    // 顶点2
    int value;      // 代价
};

struct Graph
{
    int *maxValue;   // 最长路径值
    int *root;      // 存父节点
    int **matrix;   // 邻接矩阵

} graph;

int find_array(string s[],string str,int index)
{
    for(int i=0; i<index; i++)
        if(s[i] == str)
            return i;
    return -1;
}

void criticalpath(Edge G[])
{
    int index = 0;
    for(int i=0; i<edge_num; i++)
    {
        int from =  G[i].edge_from;
        int to = G[i].edge_to;
        index = graph.maxValue[from];
        if(index + G[i].value > graph.maxValue[to])
        {
            graph.root[to] = from;
            graph.maxValue[to] = index + G[i].value;
        }
    }
}
int main()
{
    printf("案例:\n10 14\nA B 5\nA C 6\nB D 3\nC D 6\nC E 3\nD E 3\nD F 4\nD G 4\nE F 1\nE H 4\nF I 5\nG J 4\nH I 2\nI J 2\n");
    printf("请输入顶点的个数:\n");
    scanf("%d", &vertex_num);
    int k = 0, temp;
    string *str = new string[vertex_num];
    graph.maxValue = new int[vertex_num];
    graph.root = new int [vertex_num];
    graph.matrix = new int *[vertex_num];
    for(int i=0; i<vertex_num; i++)
    {
        graph.matrix[i] = new int [vertex_num];
        for(int j=0; j<vertex_num; j++)
            graph.matrix[i][j] = -1;
        graph.root[i] = -1;
        graph.maxValue[i] = 0;
    }

    Edge *edge;
    printf("请输入边的个数:\n");
    scanf("%d", &edge_num);
    edge = new Edge[edge_num];
    printf("请以\"结点A 结点B 权值\"的格式输入\n其中结点,权值为正整数\n");
    for(int i=0; i<edge_num; i++)
    {
        string a,b;
        cin >> a >> b;
        temp = find_array(str, a, k);
        if(temp != -1)
            edge[i].edge_from = temp;
        else
        {
            str[k] = a;
            edge[i].edge_from = k++;
        }

        temp = find_array(str, b, k);
        if(temp != -1)
            edge[i].edge_to = temp;
        else
        {
            str[k] = b;
            edge[i].edge_to = k++;
        }
        cin >> edge[i].value;
        graph.matrix[edge[i].edge_from][edge[i].edge_to] = edge[i].value;
    }
    printf("邻接矩阵:\n");
    for(int i=0; i<vertex_num; i++)
    {
        for(int j=0; j<vertex_num; j++)
            printf("%5d", graph.matrix[i][j]);
        cout << endl;
    }
    criticalpath(edge);
    printf("\n关键路径:\n");
    for(int i=0; i<vertex_num; i++)
    {
        stack<string> path;
        path.push(str[i]);
        int index = graph.root[i];
        cout << str[0] << "到" << str[i] << "的最早开始时间: " << graph.maxValue[i] << endl;
        while(index != -1)
        {
            path.push(str[index]);
            index = graph.root[index];
        }
        cout << "路径:";
        while(!path.empty())
        {
            cout << path.top();
            path.pop();
        }
        cout << endl;
    }
    delete[] str;
    for(int i=0; i<vertex_num; i++)
        delete[] graph.matrix[i];
    delete[] graph.matrix;
    delete[] edge;
    system("pause");
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关键路径算法(Critical Path Method,CPM)是一种用于确定项目关键路径的方法,它是一种基于网络图的算法。下面是一个基于邻接表的 C++ 实现: ```C++ #include <iostream> #include <vector> #include <queue> #include <cstring> #include <algorithm> using namespace std; // 邻接表存储图 struct edge { int to, weight; edge(int to, int weight) : to(to), weight(weight) {} }; const int MAXN = 1005; vector<edge> G[MAXN]; // 存储图 int inDegree[MAXN]; // 存储节点的入度 int earliest[MAXN]; // 存储节点的最早开始时间 int latest[MAXN]; // 存储节点的最晚开始时间 int path[MAXN]; // 存储关键路径 bool vis[MAXN]; // 标记节点是否被访问 // 拓扑排序,求每个节点的最早开始时间 void topoSort(int n) { queue<int> q; memset(earliest, 0, sizeof(earliest)); for (int i = 1; i <= n; i++) { if (inDegree[i] == 0) { q.push(i); earliest[i] = 0; } } while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < G[u].size(); i++) { int v = G[u][i].to; int w = G[u][i].weight; inDegree[v]--; earliest[v] = max(earliest[v], earliest[u] + w); if (inDegree[v] == 0) { q.push(v); } } } } // 求每个节点的最晚开始时间 void latestTime(int n) { memset(latest, 0x3f, sizeof(latest)); latest[n] = earliest[n]; for (int i = n - 1; i >= 1; i--) { for (int j = 0; j < G[i].size(); j++) { int v = G[i][j].to; int w = G[i][j].weight; latest[i] = min(latest[i], latest[v] - w); } } } // 求关键路径 void searchPath(int u) { vis[u] = true; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i].to; int w = G[u][i].weight; if (earliest[u] + w == earliest[v] && latest[u] - w == latest[v]) { path[v] = 1; if (!vis[v]) { searchPath(v); } } } } // 主函数 int main() { int n, m; cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; G[u].push_back(edge(v, w)); inDegree[v]++; } topoSort(n); latestTime(n); searchPath(1); cout << "关键路径为:"; for (int i = 1; i <= n; i++) { if (path[i]) { cout << i << " "; } } cout << endl; return 0; } ``` 输入格式为: ``` 节点个数 边数 起点 终点 权值 起点 终点 权值 ... ``` 输出关键路径

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值