codeup 关键路径 模板

#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
const int SIZE = 100;
/*
第一行输入一个正整数n(1<=n<=5),其代表测试数据数目,即图的数目

第二行输入x(1<=x<=15)代表顶点个数,y(1<=y<=19)代表边的条数

第三行给出图中的顶点集,共x个小写字母表示顶点

接下来每行给出一条边的始点和终点及其权值,用空格相隔,每行代表一条边。
*/
int n, x, y;
struct Edge {
    int v;
    int w;

    Edge(int v, int w) : v(v), w(w) {}
};

vector<Edge> adj[SIZE];
int ve[SIZE], vl[SIZE], in[SIZE];
char c[SIZE];
stack<int> st;
queue<int> qu;

bool topologicalSort() {
    queue<int> q;
    int num = 0;
    for (int i = 0; i < x; i ++) {
        if (in[c[i] - 'a'] == 0)  {
            q.push(c[i] - 'a');
        }
    }

    while (!q.empty()) {
        int u = q.front();    q.pop();
        qu.push(u);
        st.push(u);
        num ++;
        for (int i = 0; i < adj[u].size(); i ++) {
            int v = adj[u][i].v;
            int w = adj[u][i].w;
            in[v] --;
            if (in[v] == 0) q.push(v);
            if (ve[u] + w > ve[v])  ve[v] = ve[u] + w;
        }
    }

    if (num == x)   return true;
    else return false;
}

int CriticalPath() {
    fill(ve, ve + SIZE, 0);
    if (topologicalSort() == false) {
        return -1;
    }

    int maxVe = -1;
    for (int i = 0; i < SIZE; i ++) {
        if (ve[i] > maxVe)  maxVe = ve[i];
    }

    fill(vl, vl + SIZE, maxVe);

    while (!st.empty()) {
        int u = st.top(); st.pop();
        for (int i = 0; i < adj[u].size(); i ++) {
            int v = adj[u][i].v;
            int w = adj[u][i].w;

            if (vl[v] - w < vl[u]) {
                vl[u] = vl[v] - w;
            }
        }
    }

    while (!qu.empty()) {
        int u = qu.front(); qu.pop();
        for (int j = 0; j < adj[u].size(); j ++) {
            
            int v = adj[u][j].v;
            int w = adj[u][j].w;

            int e = ve[u];  int l = vl[v] - w;

            if (e == l) {
                printf("(%c,%c) ", u + 'a', v + 'a');
            }
        }
    }

    return maxVe;
}

int main() {
    scanf("%d", &n);

    while (n --) {
        for (int i = 0; i < SIZE; i ++) {
            adj[i].clear();
        }
        fill(in, in + SIZE, 0);
        scanf("%d %d", &x, &y);
        getchar();
        for (int i = 0; i < x; i ++)  scanf("%c", &c[i]);
        getchar();
        char c1, c2;
        int w;

        for (int i = 0; i < y; i ++) {
            scanf("%c %c %d", &c1, &c2, &w);
            getchar();
            Edge e(c2 - 'a', w);
            adj[c1 - 'a'].push_back(e);

            in[c2 - 'a'] ++;
        }

        printf("%d\n", CriticalPath());        
    }
    cin >> n;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值