29

严蔚敏视频 笔记29

每一对顶点之间的最短路径

vivj的所有存在路径中选出一条长度最短的路径

算法:
<vi,vj>存在,则存在路径{vi,v1,vj}
//
路径中所含顶点序号不大于
1
{vi,…,v2},{v2,…,vj}存在

则存在一条路径{vi,…,v2,…,vj}
//
路径中所含顶点序号不大于
2

依此类推,则vivj的最短路径应是上述这些路径中长度最小者

7.7 拓扑排序
以有向图表示一个工程的施工图或程序的数据流图,则图中不允许出现回路

拓扑排序
按照有向图给出的次序关系,将图中顶点排成一个线性序列,对于有向图中没有限定次序关系的顶点,则可以人为加上任意的次序关系
由此得拓扑有序序列

如何进行拓扑排序
一、从有向图中选取一个没有前驱的顶点,并输出
二、从有向图中删除此顶点以及所有从它为尾的弧
三、重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止

无前驱的顶点==入度为0的顶点
删除顶点及以它为尾的弧==弧头顶点的入度减1

取入度为零的顶点v
while(v!=0) {
    printf(v); ++m;
    w=FirstAdj(v);
    while(w!=0) {
        InDegree[w]--;
        w=NextAdj(v,w);
    }
    //
取下一个入度为0的顶点
    if(m<n) printf("
图中存在回路");
}

为避免每次都要搜索入度为0的顶点,设置栈
CountInDegree(G,indegree); //
对各顶点求入度
InitStack(S);
for(i=0;i<G.vexnum;++i)
    if(!indegree[i]) Push(S,i); //
入度为零的顶点入栈
count=0; //
对输出顶点计数
while(!EmptyStack(S)) {
    Pop(S,v); ++count; printf(v);
    for(w=FirstAdj(v);w;w=NextAdj(G,v,w))
        --indegree(w);
    if(!indegree[w]) Push(S,w); //
新产生的入度为零的顶点入栈
}
if(count<G.vexnum) printf("
图中有回路");

7.8 关键路径
以有向网表示一施工流图,弧上权值表示完成该项子工程所需时间,求将影响整个工程完成期限的子工程项

整个工程完成的时间为从有向图的源点到汇点的最长路径

关键活动:该弧上的权值增加将使有向图上的最长路径的长度增加

事件(顶点)的最早发生时间ve(j)
ve(j)=
从源点到顶点j的最长路径长度

事件(顶点)的最迟发生时间vl(k)
vl(k)=
从顶点k到汇点的最短路径长度

假设第i条弧为<j,k>
则第i项活动

活动(弧)的最早开始时间ee(i)
ee(i)=ve(j)
活动(弧)的最晚开始时间
el(i)
el(i)=vl(k)-dut(<j,k>)

事件发生时间的计算公式
ve(
源点)=0
ve(k)=Max{ve(j)+dut(<j,k>)}

vl(汇点)=ve(汇点)
vl(j)=Min{vl(k)-dut(<j,k>)}

算法实现要点
ve的顺序应该是按拓扑有序的次序
vl的顺序应该是按拓扑逆序的次序
因为拓扑逆序序列即为拓扑有序序列的逆序列
应该在拓扑排序的过程中另设一个记下拓扑有序序列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值