1.AOV网和AOE网
超级源点和超级汇点:
10.7.2 最长路径:
10.7.3 关键路径:
/*
拓扑排序:
1.设置栈 int类型 topOrder
2.bool拓扑排序函数:
1.设置队列q
2.for循环,将所有入度为0的点放入到队列q中
3.while循环:
1.取出队首元素
2.弹出
3.将u加入到拓扑序列中
4.for循环:
1.取出当前u下的结点v
2.对应的入度数--
3.如果入度数为0,则入队
5.用ve[u]来更新u的所有后继结点
4.如果栈的长度为n,则返回true;否则返回false
*/
stack<int> topOrder;
bool tuopu()
{
queue<int> q;
for(int i=0; i<n; i++)
if(inDegree[i]==0)
q.push(i);
while(!q.empty())
{
int u=q.front();
q.pop();
topOrder.push(u);
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i].v; //G时数组结构
inDegree(v)--;
if(inDegree(v)==0)
q.push(v);
}
if(ve[u]+G[u][i].w>ve[v])
ve[v]=ve[u]+G[u][i].w;
}
if(topOrder.size()==n)
return true;
else
return false;
}
/*
1.对数组v1初始化,初始值为终点的ve值
2.直接使用topOrder出栈即为你拓扑排序
3.while循环:栈topOrder不为空
1.设置u为栈顶元素
2.弹出
3.for循环
1.找到G[u][i]的结点v
2.用u的后继点v的vl来更新vl[u]
*/
fill(v1,v1+n,ve[n-1]);
while(!topOrder.empty())
{
int u=topOrder.top();
topOrder.pop();
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i].v;
if(vl[u]>vl[v]-G[u][i])
vl[u]=vl[v]-G[u][i].w;
}
}
/*
e l分别表示活动ar最早开始时间和最晚开始时间
ve vl分别表示最早发生时间和最晚发生时间
e[r]=ve[i]
vl[j]-length[r]=l[r]
关键路径,不是有向无环图返回-1,否则返回关键路径长度
int类型 CriticalPath()
1.初始化ve数组的值为0
2.如果不是有向无环图返回-1
3.初始化vl数组,初始值为ve数组的最后一个值
4.使用topOrder出栈
1.while循环 topOrder不为空
2.取出栈顶元素
3.弹出
4.for循环:
1.遍历u的所有后继点
2.设置int类型v为u的后继节点
3.用u的所有后继节点v的vl值来更新vl[u] 为了找出vl[v]-G[u][i].w的最小值
5.遍历邻接表的所有边,计算活动的最早开始时间e和最迟开始时间l
1.双层for循环:
1.分别取出v和w
2.活动最早开始时间e为ve[u] 最晚开始时间 l为 vl[v]-w
如果e为l
输出关键活动
6.返回关键路径长度:ve[n-1]
*/
int CriticalPath()
{
memset(ve,0,sizeof(ve));
if(tuopu()==false)
return -1;
fill(vl,vl+n,ve[n-1]);
while(!topOrder.empty())
{
int u=topOrder.top();
topOrder.pop();
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i].v;
if(vl[v]-G[u][i].w<vl[u])
vl[u]=vl[v]-G[u][i].w;
}
}
for(int u=0; u<n; u++)
for(int i=0; i<G[u].size(); 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",e,l);
}
return ve[n-1];
}
int maxlength=0;
for(int i=0; i<n; i++)
{
if(ve[i]>maxlength)
maxlength=ve[i];
}
fill(ve,ve+n,maxlength);