#include <iostream>
#include <vector>
#include <queue>
#include <stdio.h>
#include <string>
#include <cstring>
using namespace std;
struct Edge{
int to;
int length;
Edge(int t,int l):to(t),length(l){}
};
vector<Edge> graph[100];
int indegree[100];
int earlytime[100];
int latetime[100];
vector<int> result;
void CriticalPath(int n){
queue<int> myQueue;
for(int i=0;i<n;i++){
if(indegree[i]==0){
myQueue.push(i);
earlytime[i]=1;
}
}
//从头开始
while(!myQueue.empty()){
int u=myQueue.front();
myQueue.pop();
result.push_back(u);
for(int i=0;i<graph[u].size();i++){
int v=graph[u][i].to;
int l=graph[u][i].length;
//最早开始时间
earlytime[v]=max(earlytime[v],earlytime[u]+l);
indegree[v]--;
if(indegree[v]==0){
myQueue.push(v);
}
}
}
//-----------------前面基本和拓扑排序一样,只加了最早开始时间的计算
//倒着来
for(int i=result.size()-1;i>=0;i--){
int u=result[i];
if(graph[u].size()==0){
latetime[u]=earlytime[u];
}else{
latetime[u]=10000;
}
for(int j=0;j<graph[u].size();j++){
int v=graph[u][j].to;
int l=graph[u][j].length;
//最晚开始时间
latetime[u]=min(latetime[u],latetime[v]-l);
}
}
}
int main(){
int n,m,from,to,length;
int a=0;
scanf("%d%d",&n,&m);
memset(latetime,0, sizeof(latetime));
memset(earlytime,0, sizeof(earlytime));
memset(indegree,0, sizeof(indegree));
for(int i=0;i<m;i++){
scanf("%d%d%d",&from,&to,&length);
graph[from].push_back(Edge(to,length));
indegree[to]++;
}
CriticalPath(n);
cout<<endl;
for(int i=0;i<n;i++){
a=max(a,latetime[i]);
cout<<earlytime[i]<<" "<<latetime[i]<<endl;
}
cout<<a;
return 0;
}
关键路径长度和结点最早最晚开始时间
最新推荐文章于 2023-06-23 19:34:01 发布