AOE网:有向图的边表示活动的网
边:活动
权值:活动持续时间
关键路径:从起点到终点具有最大长度的路径
关键活动:关键路径上的活动
1.事件最早发生时间etv :顶点最早发生时间(前面的事件都发生了)
2.事件最晚发生时间ltv :顶点最晚发生时间(超出该时间则会耽误整个进程)
3.活动最早开始时间ete :弧最早发生时间
4.活动最晚开始时间lte :弧最晚发生时间
若活动最早发生时间与最晚发生时间相等,则该活动在关键路径上
前向星(存边)
typedef struct bian
{
int to,w,next;
} bian;
bian a[M];
void qiangxiangxin(int v,int u,int k)
{
in[u]++;
a[countt].to=u;
a[countt].w=k;
a[countt].next=pre[v];
pre[v]=countt++;
}
bool TopologicalSort()//拓扑排序的同时求出事件最早发生时间
{
int countt=0;
int gettop;
for(int i=0; i<m; i++)
if(in[i]==0)
w.push(i);
for(int i=0; i<m; i++)
etv[i]=0;
while(!w.empty())
{
gettop=w.top();
w.pop();
countt++;
e.push(gettop);//存储拓扑序列
for(int i=pre[gettop]; i!=-1; i=a[i].next)
{
int y=a[i].to;
if(!(--in[y]))
{
w.push(y);//拓扑排序
}
//cout<<etv[gettop]+a[i].w<<endl;
if(etv[gettop]+a[i].w>etv[y])
etv[y]=etv[gettop]+a[i].w;
}
}
//for(int i=1;i<=n;i++)
// cout<<etv[i]<<" ";
if(countt<n)
return false;
else
return true;
}
找到关键路径
void CriticalPath()
{
int ete,lte;
TopologicalSort();
int ltv[M];
for(int i=0; i<m; i++)
ltv[i]=etv[m-1];
while(!e.empty())
{
int gettop=e.top();
e.pop();
for(int i=pre[gettop]; ~i; i=a[i].next)
{
int k=a[i].to;
if(ltv[k]-a[i].w<ltv[gettop])
ltv[gettop]=ltv[k]-a[i].w;
}
}
for(int i=0; i<m; i++)
{
for(int j=pre[i]; j!=-1; j=a[j].next)
{
int y=a[j].to;
ete=etv[i];//事件的最早发生时间==活动最早发生时间
lte=ltv[y]-a[j].w;//活动最晚发生时间
if(ete==lte)
{
printf("<v%d,v%d> length: %d , \n",i,y,a[j].w);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=0; i<m; i++)
pre[i]=-1;
for(int i=1; i<=n; i++)
{
cin>>v>>u>>k;
qiangxiangxin(v,u,k);
}
CriticalPath();
return 0;
}
/*4 4
0 1 3
0 2 4
1 3 5
2 3 8*/