关键路径

#include<iostream>

#include<stack>

#include<string>

using namespace std;

#define maxEdge 0x3f3f3ff

const int MAX_V_NUM=100;         //点的最大值

int Edges[MAX_V_NUM][MAX_V_NUM];//图的邻接矩阵

int indegree[MAX_V_NUM];       //存储各顶点的入度

string Vert[MAX_V_NUM];       //顶点信息

int TE[MAX_V_NUM];           //顶点的最早开始时间

int TL[MAX_V_NUM];          //顶点的最晚开始时间

int n;                     //点

int m;                    //边

stack<int>S;             //拓扑排序序列

stack<int>Sq;           //逆拓扑排序序列

int TopologicalSort()

{

         int i,j,count;

         for(i=1;i<=n;i++)

                   for(j=1;j<=n;j++)

                            if(Edges[j][i]<maxEdge&&Edges[j][i]!=0)

                                     indegree[i]++;

        

         for(i=1;i<=n;i++)

                   if(!indegree[i])

                            S.push(i);

         count=0;

         for(i=0;i<n;i++)//赋初值

                   TE[i]=0;

         while(!S.empty())

         {

                   i=S.top();

                   S.pop();

                   Sq.push(i);

                   count++;

                   for(j=1;j<=n;j++)

                            if(Edges[i][j]<maxEdge&&Edges[i][j]!=0)

                            {

                                     indegree[j]--;

                                     if(!indegree[j])

                                               S.push(j);

                                     if(TE[i]+Edges[i][j]>TE[j])//求vi的直接后继vj的最早发生时间取大的

                                               TE[j]=TE[i]+Edges[i][j];

 

                            }

         }

         if(count<n)

                   return -1;

         else

                   return 1;

}

 

void CriticalPath()

{

         int i,j;

         if(TopologicalSort()==-1)

         {

                   cout<<"该路径无关键路径。。。"<<endl;

                   exit(0);

         }

         for(i=1;i<=n;i++)//初始化每点的最迟开始时间

                   TL[i]=TE[n];

         while(!Sq.empty())

         {

                   i=Sq.top();

                   Sq.pop();

                   for(j=1;j<=n;j++)

                            if(Edges[i][j]<maxEdge&&Edges[i][j]!=0)

                            {

                                     if(TL[j]-Edges[i][j]<TL[i])//逆拓扑排序求每点的最迟开始时间(后继结点减去edges[i][j])取小的

                                               TL[i]=TL[j]-Edges[i][j];

                            }

         }

         cout<<"关键路径为:"<<endl;

         for(i=1;i<=n;i++)

                   for(j=1;j<=n;j++)

                   {

                            if(Edges[i][j]<maxEdge&&Edges[i][j]!=0)

                                     if(TE[i]==TL[j]-Edges[i][j])

                                               cout<<"("<<Vert[i]<<","<<Vert[j]<<","<<Edges[i][j]<<")"<<endl;

                   }

 

 

 

}

int main()

{

         int i,j,u,v,w;

         cout<<"请输入点的个数和边的条数"<<endl;

    cin>>n>>m;

         for(i=1;i<=n;i++)

                   for(j=1;j<=n;j++)

                   {

                            if(i==j)

                                     Edges[i][j]=0;

                            else

                                     Edges[i][j]=maxEdge;

                   }

   cout<<"请输入点的信息"<<endl;

   for(i=1;i<=n;i++)

            cin>>Vert[i];

   cout<<"请输入每条边对应的顶点下标和权值"<<endl;

   for(j=1;j<=m;j++)

   {

            cin>>u>>v>>w;

            Edges[u][v]=w;

   }

   TopologicalSort();

   CriticalPath();

 

 

   return 0;

 

}

 

/*

9 11

v1 v2 v3 v4 v5 v6 v7 v8 v9

1 2 6

1 3 4

1 4 5

2 5 1

3 5 1

4 6 2

6 8 4

5 7 9

5 8 7

7 9 2

8 9 4

*/

posted @ 2012-12-07 16:01  ♂咱說 ろ算  阅读(263)  评论(0编辑  收藏  举报