因为没怎么找到一些关键路径的练习题,自己编了一个,学以致用
/*
描述如下:
我们保证只有一个源点和汇点;
第一行输入顶点数 n 和边数 m
下列m行为起点到目标顶点编号以及距离(从1开始编号!想要fill的注意了(终点必须是arr+n+1,起点无所谓了))
7 8
1 2 1
1 3 2
2 4 3
3 4 3
4 5 2
4 6 1
5 7 3
6 7 3
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1001;
const int INF=INT_MAX;
struct Edge{
int to;
int length;
Edge(int t,int l):to(t),length(l){}
};
vector<Edge>graph[MAXN];
int earliest[MAXN];//和拓扑排序相比,多加了两个数组 ;正向找最大值的earliest(咱们最迟啥时候做这件事)
int latest[MAXN];//和拓扑排序相比,多加了两个数组 :逆向到最小值的latest
int inDegree[MAXN];
void Criticalpath(int n)
{
queue<int>myqueue;
stack<int>mystack;
for(int i=1;i<=n;i++)
{
if(inDegree[i]==0) myqueue.push(i);
}
while(!myqueue.empty())
{
int u=myqueue.front();
myqueue.pop();
mystack.push(u);
for(int i=0;i<graph[u].size();i++)
{
int v=graph[u][i].to;
int l=graph[u][i].length;
inDegree[v]--;
earliest[v]=max(earliest[v],earliest[u]+l);//正序找最大的
if(inDegree[v]==0) myqueue.push(v);
}
}
while(!mystack.empty())
{
int u=mystack.top();
mystack.pop();
if(graph[u].size()==0)
{
latest[u]=earliest[u];
}
for(int i=0;i<graph[u].size();i++)
{
int v=graph[u][i].to;
int l=graph[u][i].length;
latest[u]=min(latest[u],latest[v]-l);//逆序找最小的
}
}
return ;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(graph,0,sizeof(graph));
memset(earliest,0,sizeof(earliest));
fill(latest,latest+n+1,INF);
memset(inDegree,0,sizeof(inDegree));
while(m--)
{
int from,to,length;
scanf("%d%d%d",&from,&to,&length);
graph[from].push_back(Edge(to,length));
inDegree[to]++;
}
Criticalpath(n);
int answer=0;
for(int i=1;i<=n;++i)//++i的效率高的呀!
{
if(latest[i]==earliest[i])
{
answer=max(answer,earliest[i]);
cout<<"关键路径的节点为:"<<i<<endl;
}
}
printf("关键路径总长度为:%d\n",answer);
}
return 0;
}