关键路径
#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
*/