严蔚敏视频 笔记28
7.5 重(双)连通图和关节点
若从一个连通图中删去任何一个顶点及其相关联的边仍为一个连通图,则该连通图被称为重(双)连通图
若连通图中某个顶点和其相关联的边被删去之后,该连通图被分割成两个或两个以上的连通分量,则称此顶点为关节点
关节点特征:
深度优先搜索遍历得到深度优先生成树
若生成树上的根结点,有两个或两个以上的分支,则此顶点必为关节点
对生成树上的任意一个“顶点”,若其某棵子树的根或子树中的其他顶点没有和其祖先相通的回边,则该定点必为关节点
如何求关节点
1)设V0为深度优先遍历的出发点
p=G.vertices[V0].firstarc;
v=p->adjvex;
DFSArticul(G,v); // 从第v顶点出发深度优先搜索
if(count<G,vexnum) // 生成树的根至少有两棵子树
printf(0,G.vertices[0].data); // 根是关节点
2)对生成树上的顶点定义一个函数:
low(v)=Min(visited[v],low[w],visited[k]);
visited代表访问次序 w是v在生成树上的子树根 k是与v有回边相通的祖先
若low[w]>=visited[v]则v为关节点
对深度优先遍历算法作修改:
visited[v]的值改为遍历过程中顶点的访问次序count值
遍历过程中求得low[v]=Min(visited[v],low[w],visited[k])
从子树遍历返回时判别low[w]>=visited[v]?
算法:
min=visited[v0]=++count;
// 设定low[v0]的初始值count计顶点访问次序
for(p=G.vertices[v0].firstarc;p;p=p->nextarc) {
w=p->adjvex; // w为v0的邻接顶点
if(visited[w]==0) { // w未曾被访问
DFSArticul(G,w); // 返回前求得low[w]
if(low[w]<min) min=low[w];
if(low[w]>visited[v0]) printf(v0,G.vertices[v0].data); // 输出关节点
}
else // w是回边上的顶点
if(visited[w]<min) min=visited[w];
}
low[v0]=min;
7.6 两点之间的最短路径问题
从源点到其余各点的最短路径
依路径长度递增的次序求得各条路径
Dist[k]表示当前所求得的从源点到顶点k的最短路径
一般情况下Dist[k]
=<源点到顶点k的弧上的权值>
或=<源点到其他顶点的路径长度>+<其他顶点到顶点k弧上的权值>