输出关键路径

Graph.h

#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include <iostream>
#include <cstdlib>

using namespace std;
//链表结构
typedef struct ListNode {
    int index;
    int weight;
    struct ListNode *next;
}ListNode;
//顶点结构
typedef struct Vertex{
    int indegree;
    ListNode *firstvex;
    char data;
}Vertex;
//图结构
typedef struct Graph{
    Vertex vertex[256];
    int vexnum , edgenum;
}Graph;

void Init(Graph &G);
void Create_Graph(Graph &G);

void Init(Graph &G){
    G.edgenum = 0;
    G.vexnum = 0;
}

void Create_Graph(Graph &G){
    cout << "请输入顶点数:" ;
    cin >> G.vexnum;
    cout << "请输入边数:";
    cin >> G.edgenum;
    int i , j , k;
    //第0号位置不用,输入顶点
    for (i = 1 ; i <= G.vexnum ; i++){
        cout << "第" << i << "个顶点为:";
        cin >> G.vertex[i].data;
        G.vertex[i].firstvex = NULL;
        G.vertex[i].indegree = 0;
    }
    //输入边
    int weight;
    for(int k = 0 ; k < G.edgenum ; k++){
        cout << "请输入边(vi , vj)的下标i,j:";
        cin >> i >> j;
        cout << "请输入(" << i << "," << j << ")的权值: ";
        cin >>  weight;
        //构造边即将顶点下标存入链结构中
        //前插法,尾插法需要遍历好麻烦
        ListNode *e = new ListNode;
        e->index = j;
        e->next = G.vertex[i].firstvex;
        e->weight = weight;
        G.vertex[i].firstvex = e;

        G.vertex[j].indegree++;
    }
}

#endif // GRAPH_H_INCLUDED
#ifndef KEYPATH_H_INCLUDED
#define KEYPATH_H_INCLUDED
#include <iostream>
#include "Graph.h"
#include <stack>

using namespace std;
//拓扑逆序栈
stack<int> T;
//入度为零节点栈
stack<int> S;
int ve[256];
int vl[256];
//拓扑排序
bool TopologicalOrder(Graph G){
    //记录入度为零的顶点
    int count = 0;
    int i;
    //初始化时间最早发生时间为0
    for(i = 1 ; i <= G.vexnum ; i++){
        ve[i] = 0;
    }
    //将起点入零入度栈
    S.push(1);
    ListNode *p;
    int j , k;
    while(!S.empty()){
        j = S.top();
        S.pop();
        T.push(j);
        count++;
        //深度遍历当前入度为零的节点,将其相邻节点的入度减一
        for( p = G.vertex[j].firstvex ; p ; p = p->next){
            k = p->index;
            //相邻节点入度减为零则入栈
            if(--G.vertex[k].indegree == 0){
                S.push(k);
            }
            //事件k的最早开始时间是前一个相邻节点最早发生时间
            //加上路径权值中最大的那个即MAX{ve[j] + weight}
            if(ve[j] + p->weight > ve[k]){
                ve[k] = ve[j] + p->weight;
            }
        }
    }

    if(count < G.vexnum){
        return false;
    }
    else return true;
}

void CriticalPath(Graph G){

    if(!TopologicalOrder(G)){
        cout << "没有拓扑路径";
        exit(1);
    }
    int i;
    //初始化将最晚发生时间赋值为终点的最晚发生时间
    //因为终点最晚发生时间与最早发生时间一致且为最大值
    for(i = 1 ; i <= G.vexnum ; i++){
        vl[i] = ve[G.vexnum];
    }

    while(!T.empty()){
        //j,k代表边<j , k>
        int j = T.top();
        T.pop();
        ListNode *p;
        int k;
        //第一次终点的相邻节点为NULL不执行
        for(p = G.vertex[j].firstvex ; p ; p = p->next){
            k = p->index;
            if(vl[k] - p->weight < vl[j]){
                vl[j] = vl[k] - p->weight;
            }
        }
    }

    int k , j;
    ListNode *p;
    for(j = 1 ; j <= G.vexnum ; j++){
            //第一种方法判断关键路径
//            for(p = G.vertex[j].firstvex ; p ; p = p->next){
//                k = p->index;
//                int ee = ve[j];
//                int el = vl[k] - p->weight;
//                if(ee == el){
//                    cout << G.vertex[j].data << " ";
//                }
//            }

//第二种方法判断关键路径
            if(ve[j] == vl[j]){
                cout << G.vertex[j].data << " ";
            }
        }
//    cout << G.vertex[G.vexnum].data;
}


#endif // KEYPATH_H_INCLUDED
#include <iostream>
#include "Graph.h"
#include "KeyPath.h"

using namespace std;

int main()
{
    Graph G;
    Init(G);
    Create_Graph(G);
    CriticalPath(G);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值