AOE网中,节点代表事件,边代表活动,最早开始时间和最晚开始时间相等的是关键活动
u->v u是活动开始事件,v是活动结束事件,w为活动耗时
活动的最早开始时间为事件u的最早开始时间,
最晚开始时间是事件v的最晚开始时间-w
不知道为什么最大随机没过
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=200;
struct node
{
int v,w;
node(int v,int w):v(v),w(w){}
};
vector<node> g[N];
int n,m;
int e[N],l[N],ve[N],vl[N]; //活动最早开始时间 活动最晚开始时间 事件最早开始时间 事件最晚开始时间
int indegree[N]={0};
stack<int> topo;
bool topo_sort()
{
queue<int> q;
for(int i=1;i<=n;++i)
if(!indegree[i])
q.push(i);
while(!q.empty())
{
int u=q.front();q.pop();
topo.push(u);
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i].v;
indegree[v]--;
if(!indegree[v])
{
q.push(v);
}
if(ve[u]+g[u][i].w>ve[v]) //事件最早开始时间是前驱事件全部完成的最后一个
{
ve[v]=ve[u]+g[u][i].w;
//cout<<ve[v]<<endl;
}
}
//g[u].clear();
}
if(topo.size()==n) return true;
else return false;
}
int CriticalPath()
{
//cout<<ve[n]<<endl;
for(int i=1;i<=n;++i)
vl[i]=ve[n];
while(!topo.empty()) //用u的所有后继结点的最晚开始时间来更新u的最晚开始时间
{
int u=topo.top();
topo.pop();
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i].v;
if(vl[u]>vl[v]-g[u][i].w) //vl[u]=min()
{
vl[u]=vl[v]-g[u][i].w;
}
}
}
for(int u=1;u<=n;++u) //交接的小的先输出
for(int i=g[u].size()-1;i>=0;--i)//一样则按输入顺序的倒序输出
{
int v=g[u][i].v,w=g[u][i].w;
int e=ve[u],l=vl[v]-w;
if(e==l)
printf("%d->%d\n",u,v);
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;++i)
{
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(node(v,w));
//g[v].push_back(node(u,w));
indegree[v]++;
}
memset(ve,0,sizeof(ve));
if(topo_sort()==false)
{
cout<<0<<endl;
return 0;
}
cout<<ve[n]<<endl;
CriticalPath();
return 0;
}
/*
最大N,随机,可行 Wrong Answer 2 ms 508 KB -4
*/