前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关键路径-STL版

关键路径-STL版

作者头像
叶茂林
发布2023-07-30 13:31:16
2470
发布2023-07-30 13:31:16
举报
文章被收录于专栏:叶子的开发者社区

题目描述

给定有向图无环的边信息,求每个顶点的最早开始时间、最迟开始时间。

// 参考代码

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;

class Vertex {
public:
    int indexNo;
    bool hasEnterQueue;
    int early;
    int later;

    Vertex(int indexNo) {
        this->indexNo = indexNo;
        this->hasEnterQueue = false;
        early = -1;
        later = 0x7FFFF;
    }
    void updateEarly(int parentEarly, int edgeValue) {
        int newEarly = parentEarly + edgeValue;
        if (newEarly > this->early)
            this->early = newEarly;
    }
    void updateLater(int childLater, int edgeValue) {
        int newLater = childLater - edgeValue;
        if (newLater < this->later)
            this->later = newLater;
    }
};


class Graph {
public:
    vector<Vertex> vertexes;
    vector<vector<int> > adjMat;
    int n;
public:
    void readVertexes() {
        //TODO: 将顶点数读入成员变量n
        
        //TODO: 从输入初始化vertexes数组
        int i=0;
        for(; i<n; ++i) {
            Vertex v(i);
            this->vertexes.push_back(v);
        }
        
        //为成员变量adjMat创建内存,赋初值
        for(i=0; i<n; ++i) {
            vector<int> row;
            int j=0;
            for(; j<n; ++j) {
                //TODO: 将0增加到row最后
            }
           //TODO: 将row增加到adjMat最后
        }
    }
    void readAdjMatrix() {
        //read the adjacent info into this->adjMat
        int edges;
        cin >> edges;
        int i=0;
        int s, t, w;  //s源顶点编号,t目的顶点编号,w边长
        for(; i<edges; ++i) {
            //TODO: 读入s,t,w,并将adjMat的第s行、第t列的值改为w.
        }
    }

    void updateEarly(int parentNo, queue<int>& earlyQue) {
        int parentEarly = vertexes[parentNo].early;  //读入父结点early值

        int j=0;
        for(; j<n; ++j) {
            int edgeValue = adjMat[parentNo][j];
            if (edgeValue == 0) continue;  //若父结点与结点j没有边相连,pass

            Vertex& child = vertexes[j];
            child.updateEarly(parentEarly, edgeValue); //更新子结点j的early信息

            if(!child.hasEnterQueue) {
                child.hasEnterQueue = true; //将子结点加入队列
                earlyQue.push(j);
            }
        }
    }
    void updateLater(int childNo, queue<int>& laterQue) {
        //TODO:
    }

    int getRoot() {
        //获取入度为0的顶点
        int j=0;
        for(; j<n; ++j) {
            int i=0;
            for(; i<n && adjMat[i][j] == 0; ++i);
            if (i>=n) return j; //j has not any in-edges.
        }
        return -1;  //表示没找到
    }
    int getLeaf() {
        //TODO: 获取出度为0的顶点
    }

    void printEarlyLater(bool isEarly) {
        int i=0;
        for(; i<n; ++i) {
            Vertex& v = vertexes[i];
            if (isEarly)
                cout << v.early << " ";
            else {
                cout << v.later << " ";
            }
        }
        cout << endl;
    }

    void findEarly() {
        //执行关键路径算法,求每个顶点的最早开始时间。
        int r = getRoot();
        Vertex& root = vertexes[r];
        root.hasEnterQueue = true;
        root.early = 0;

        queue<int> que;
        que.push(r);

        while(!que.empty()) {
            int p = que.front();
            que.pop();

            updateEarly(p, que);
        }

        printEarlyLater(true);
    }
    void clearEnterQueue() {
        int i=0;
        for(; i<n; ++i) {
            vertexes[i].hasEnterQueue = false;
        }
    }
    void findLater() {
        //TODO:调用clearEnterQueue,以清除每个顶点的hasEnterQueue=false
        //执行关键路径算法,求每个顶点的最迟开始时间。
    }

    void main() {
        readVertexes();
        readAdjMatrix();
        findEarly();
        findLater();
    }
};


int main() {
    int t=1;
    //cin >> t;
    while (t--) {
        Graph g;
        g.main();
    }
    return 0;
}

输入

第一行图的顶点总数

第二行边的总数

第三行开始,每条边的时间长度,格式为源结点   目的结点   长度

输出

第一行:第个顶点的最早开始时间

第二行:每个顶点的最迟开始时间

输入样例1 

9 12 0 1 3 0 2 10 1 3 9 1 4 13 2 4 12 2 5 7 3 6 8 3 7 4 4 7 6 5 7 11 6 8 2 7 8 5

输出样例1

0 3 10 12 22 17 20 28 33  0 9 10 23 22 17 31 28 33 

思路分析

它给的代码是存在严重缺陷的,不能用。

AC代码

代码语言:javascript
复制
#include<iostream>
using namespace std;
const int max_number=200;
int main(){
    int vertex_number,edge_number,origin,terminal;
    cin>>vertex_number>>edge_number;
    int matrix[max_number][max_number]={0};
    int inDegree[max_number]={0};
    int topology[max_number];
    for(int i=0;i<edge_number;i++){
        cin>>origin>>terminal;
        cin>>matrix[origin][terminal];
    }
    for(int i=0;i<edge_number;i++)
        for(int j=0;j<edge_number;j++)
            if(matrix[j][i])
                inDegree[i]++;
    int count=0;                            //topology sort
    while(count<vertex_number){
        for(int i=0;i<vertex_number;i++)
            if(inDegree[i]==0){
                topology[count++]=i;
                inDegree[i]=-1;
            for(int j=0;j<vertex_number;j++)
                if(matrix[i][j])
                    inDegree[j]--;
            }
    }
    int anti_topology[max_number];
    for(int i=0;i<vertex_number;i++)
        for(int j=0;j<vertex_number;j++)
            if(i==topology[j])
                anti_topology[i]=j;
    int ve[max_number]={0};
    int vl[max_number]={0};
    int vve[max_number]={0};
    int vvl[max_number]={0};
    for(int i=1;i<vertex_number;i++){
        int max=0;
        for(int j=0;j<vertex_number;j++)
            if(matrix[j][topology[i]]&&matrix[j][topology[i]]+ve[anti_topology[j]]>max)
                max=matrix[j][topology[i]]+ve[anti_topology[j]];
        ve[i]=max;
        vve[topology[i]]=max;
    }

    vvl[topology[vertex_number-1]]=vl[vertex_number-1]=ve[vertex_number-1];
    for(int i=vertex_number-2;i>=0;i--){
        int min=0x3f3f3f3f;
        for(int j=0;j<vertex_number;j++)
            if(matrix[topology[i]][j]&&vl[anti_topology[j]]-matrix[topology[i]][j]<min)
                min=vl[anti_topology[j]]-matrix[topology[i]][j];
        vl[i]=min;
        vvl[topology[i]]=min;
    }
    for(int i=0;i<vertex_number;i++)
        cout<<vve[i]<<' ';
    cout<<endl;
    for(int i=0;i<vertex_number;i++)
        cout<<vvl[i]<<' ';
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • 思路分析
  • AC代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档