关键路径

本文解析了2013年考研编程题目,涉及图论中的拓扑排序、关键路径长度计算、事件结束时间分析和关键活动识别。通过C++代码展示了如何使用邻接矩阵解决有向图问题,适用于算法竞赛和理解基础数据结构与算法应用。
摘要由CSDN通过智能技术生成

输入样例

参考2013年408考研真题

输出样例

测试代码

#include <bits/stdc++.h>
using namespace std;
bool toporder(const vector<vector<pair<int, int> > > &adj, vector<int> &ord, vector<int> &v_e){
    vector<int> ind(adj.size(), 0);
    for(auto &poi: adj){
        for(auto &edg: poi){
            ind[edg.second]++;
        }
    }
    queue<int> que;
    for(int poi=0; poi<(int)adj.size(); poi++){
        if(ind[poi] == 0){
            que.push(poi);
        }
    }
    v_e.resize(adj.size(), 0);
    while(!que.empty()){
        int poi = que.front();
        que.pop();
        ord.push_back(poi);
        for(auto &edg: adj[poi]){
            if(--ind[edg.second] == 0){
                que.push(edg.second);
            }
            v_e[edg.second] = max(v_e[edg.second], v_e[poi]+edg.first);
        }
    }
    if(ord.size() != adj.size()){
        return false;
    }
    return true;
}
inline int critical_path_length(const vector<int> &ord, const vector<int> &v_e){
    return v_e[ord.back()];
}
void event_last_time(const vector<vector<pair<int, int> > > &adj, const vector<int> &ord, const vector<int> &v_e, vector<int> &v_l){
    v_l.resize(adj.size(), v_e[ord.back()]);
    for(auto ptr=ord.rbegin(); ptr!=ord.rend(); ptr++){
        for(auto &edg: adj[*ptr]){
            v_l[*ptr] = min(v_l[*ptr], v_l[edg.second]-edg.first);
        }
    }
}
void critical_activity(const vector<vector<pair<int, int> > > &adj, const vector<int> &v_e, const vector<int> &v_l, vector<pair<int, int> > &c_a){
    for(int poi=0; poi<(int)adj.size(); poi++){
        for(auto edg: adj[poi]){
            int e_e = v_e[poi];
            int e_l = v_l[edg.second]-edg.first;
            if(e_e == e_l){
                c_a.push_back({poi, edg.second});
            }
        }
    }
}
int main(){
    int n, k;
    cin >> n >> k;
    vector<vector<pair<int, int> > > adj(n);
    for(int i=0; i<k; i++){
        int l, r, v;
        cin >> l >> r >> v;
        adj[l].push_back({v, r});
    }
    vector<int> ord;
    vector<int> v_e;
    if(toporder(adj, ord, v_e)){
        copy(ord.begin(), ord.end(), ostream_iterator<int>(cout, " "));
        cout << endl;
    }else{
        cout << "ERROR" << endl;
        return 0;
    }
    vector<int> v_l;
    event_last_time(adj, ord, v_e, v_l);
    vector<pair<int, int> > c_a;
    critical_activity(adj, v_e, v_l, c_a);
    cout << critical_path_length(ord, v_e) << endl;
    for(auto &i: c_a){
        cout << i.first << "->" << i.second << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值