zoukankan      html  css  js  c++  java
  • 关键路径

      1 #include"iostream"
      2 #include"string"
      3 #include"stack"
      4 using namespace std;
      5 typedef string element;
      6 struct ArcNode{        //边结点
      7     int weight;
      8     int adjuex;
      9     ArcNode *nextarc;
     10 };
     11 struct VNode{        //顶点结点
     12     element data;
     13     ArcNode *firstarc;
     14 };
     15 
     16 class Graph{
     17 private:
     18     VNode *vertex;
     19     int vernum,arcnum;
     20 public:
     21     Graph(int vernum,int arcnum){
     22         this->vernum = vernum;
     23         this->arcnum = arcnum;
     24         vertex = new VNode[vernum];
     25         for(int i = 0;i < vernum;i++){
     26             vertex[i].firstarc = NULL;
     27         }
     28     }
     29     int connected(element e){
     30         for(int i = 0;i < vernum;i++){
     31             if(e == vertex[i].data){
     32                 return i;
     33             }
     34         }
     35         cout<<"没有该顶点"<<endl;
     36         return -1;
     37     }
     38     void cinCreate(){
     39         cout<<"输入"<<vernum<<"个顶点"<<endl;
     40         for(int i = 0;i < vernum;i++){
     41             cin>>vertex[i].data;
     42         }
     43         cout<<"输入"<<arcnum<<"条边"<<endl;
     44         element v1,v2;
     45         int n1,n2;
     46         for(i = 0;i < arcnum;i++){
     47             cin>>v1>>v2;
     48             n1 = connected(v1);
     49             n2 = connected(v2);
     50             ArcNode *p = new ArcNode;
     51             p->adjuex = n2;
     52             cin>>p->weight;
     53             p->nextarc = vertex[n1].firstarc;
     54             vertex[n1].firstarc = p;
     55         }
     56     }
     57     void show(){
     58         for(int i = 0;i < vernum;i++){
     59             ArcNode *p = vertex[i].firstarc;
     60             while(p){
     61                 cout<<"<"<<vertex[i].data<<", "<<vertex[p->adjuex].data<<">"<<" : "<<p->weight<<endl;
     62                 p = p->nextarc;
     63             }
     64         }
     65     }
     66     void topoSort(int *arr){
     67         stack<int> s;
     68         //初始化indegree数组
     69         int *indegree = new int[vernum];
     70         for(int i = 0;i < vernum;i++){
     71             indegree[i] = 0;
     72         }
     73         for(i = 0;i < vernum;i++){
     74             ArcNode *p = vertex[i].firstarc;
     75             while(p){
     76                 indegree[p->adjuex]++;
     77                 p = p->nextarc;
     78             }
     79         }
     80         //入度为0的点入栈
     81         for(i = 0;i < vernum;i++){
     82             if(!indegree[i]){
     83                 s.push(i);
     84             }
     85         }
     86         //其他为0点入栈
     87         for(i = 0;i < vernum;i++){
     88             arr[i] = s.top();
     89             s.pop();
     90             ArcNode *p = vertex[arr[i]].firstarc;
     91             while(p){
     92                 if(!--indegree[p->adjuex]){
     93                     s.push(p->adjuex);
     94                 }
     95                 p = p->nextarc;
     96             }
     97         }
     98     }
     99     void shortPath(){
    100         //调用拓扑排序 排列顺序
    101         int *topolist = new int[vernum];
    102         topoSort(topolist);
    103 
    104         //最早发生时间ve
    105         int *ve = new int[vernum];            
    106         memset(ve,0,vernum * sizeof(int));        //初始化,int型只能初始化为0或-1
    107         for(int i = 0;i < vernum;i++){            //遍历所有结点
    108             int k = topolist[i];                //依次取出拓扑序列
    109             ArcNode *p = vertex[k].firstarc;    //p指向k的邻接点
    110             while(p){                            //邻接点存在
    111                 int j = p->adjuex;                //邻接点的位置(下标)
    112                 //在所有最早的时间中找到一个最迟的,(等待最迟的完成)代表该点的最早
    113                 if(ve[j] < ve[k] + p->weight){    //若k的最早时间 加 k到j 的时间 比j 的最早时间迟,存上最长时间(因为j点要等待它前面所有点完成,即时间最长的完成)
    114                     ve[j] = ve[k] + p->weight;    //ve[j]存上最早时间
    115                 }
    116                 p = p->nextarc;
    117             }
    118         }
    119 
    120         //最晚发生时间vl
    121         int *vl = new int[vernum];
    122         for(i = 0;i < vernum;i++){                //初始化为汇点的最早时间
    123             vl[i] = ve[vernum - 1];
    124         }
    125         for(i = vernum - 1;i >= 0;i--){
    126             int k = topolist[i];
    127             ArcNode *p = vertex[k].firstarc;
    128             while(p){
    129                 int j = p->adjuex;                //邻接点
    130                 if(vl[k] > vl[j] - p->weight){    //若j最迟时间 减 k到j的时间 比 k的最迟时间早,存最早(在所有最迟时间中找到一个最早的作为最迟时间,以保证所有的都不会迟到)
    131                     vl[k] = vl[j] - p->weight;
    132                 }
    133                 p = p->nextarc;
    134             }
    135         }
    136 
    137         //判断某活动是否为关键活动
    138         for(i = 0;i < vernum;i++){
    139             ArcNode *p = vertex[i].firstarc;
    140             while(p){
    141                 int j = p->adjuex;            //邻接点
    142                 int e = ve[i];                //最早活动
    143                 int l = vl[j] - p->weight;    //(最迟活动)邻接点最迟时间 减 i到j的时间
    144                 if(e == l){            //相等则为关键路径
    145                     cout<<"<"<<vertex[i].data<<", "<<vertex[j].data<<">"<<ends;
    146                 }
    147                 p = p->nextarc;
    148             }
    149         }
    150         cout<<endl;
    151     }
    152 };
    153 /*
    154 
    155 v1 v2 v3 v4 v5 v6
    156 v1 v2 6  v3 v1 1  v1 v4 5  v2 v5 3  v6 v4 2  v3 v2 5  v3 v4 5  v6 v3 4  v3 v5 6  v5 v6 6
    157 
    158 v0 v1 v2 v3 v4 v5 v6 v7 v8
    159 v0 v1 6  v0 v2 4  v0 v3 5  v1 v4 1  v2 v4 1  v3 v5 2  v4 v6 9  v4 v7 7  v5 v7 4  v6 v8 2  v7 v8 4
    160 */
    161 int main(){
    162     Graph g(9, 11);
    163     g.cinCreate();
    164 //    g.show();
    165     g.shortPath();
    166 
    167     return 0;
    168 }
    BY oleolema
  • 相关阅读:
    ubuntu查看系统负载和程序运行状况
    ubuntu 离线装包
    python如何离线装包 离线如何部署python环境
    开发板上如何配置apahe2+mysql+php7
    c++指针实例
    nginx反向代理nginx,RealServer日志打印真实ip
    lvs+keep搭建高可用web服务
    linux一键安装vncserver脚本
    ansible 学习与实践
    centos7编译安装MySQL5.7.9
  • 原文地址:https://www.cnblogs.com/oleolema/p/9027238.html
Copyright © 2011-2022 走看看