Lec07 Graph¶
一、图的概念¶
- 有向图
- 无向图
- 简单图:不存在重复边,不存在顶点到自身的边
- 多重图:某两个结点之间的边数多于一条,允许与自己连
- 完全图:简单图的特例,每两个结点均相连
- 子图
- 连通、连通图、连通分量
- 强连通:v到w与w到v均有路径
- 强连通图、强连通分量
- 生成树与生成森林
- 度
- 权
- 网:带权图
- 稠密图、稀疏图
- 路径、路径长度、回路
- 简单路径、简单回路:顶点不重复出现
- 距离:u到v的最短路径若存在,则为u到v的距离,否则距离为无穷
- 有向树:一个顶点的入度为0,其余顶点出度均为1
二、图的存储结构¶
1.邻接矩阵¶
利用一个二维数组来存储,查询行列即可。
2.邻接表¶
每一个结点u指向的结点vi,依附于一个开头为u的单链表
#来自pta的一个邻接表模型
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV;
PtrToAdjVNode Next;
};
typedef struct Vnode{
PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;
int Ne;
AdjList G;
};
typedef PtrToGNode LGraph;
3.邻接多重表¶
多用于无向图 每一个顶点用一个结点表示
每一个边也用一个结点表示
解释:其中ivex和jvex是与某条边依附的两个顶点在顶点表中下标。ilink 指向依附顶点ivex的下一条边,jlink 指向依附顶点jvex的下一条边。
三、拓扑排序¶
有向无环图一定是拓扑序列 拓扑排序就是只有从前指向后的边,没有从后指向前的边,如果是一个有向无环图,那么一定有一个点的入度为0。
1.排序思路¶
如果有入度为0的点,那么入队,将队列里的点依次出列,找到所有与这个点相邻的点,删除这条边(入度-1),如果所有都入队,那么是一个拓扑排序。
2.代码实现¶
四、最短路问题¶
基本的思路:
- 在未访问的顶点中,寻找一个和目标距离最短的顶点V
- 如果没有找到,就停止,如果找到了,将V标记位已访问
- 对所有和V相邻的节点W,更新最多路径距离的值
五、Network Flow Problems最大流问题¶
最大流问题,决定最大能入多少管道
A Simple Algorithm¶
- 三幅图 原图-流图-残差图
- augmenting path 增长通路 选定一条路径,取最大的流量,在流图上添加流量,在残差图上进行做差,如果残差图中为0那么删除
To Be Greedy 如果先选最大路径¶
我们需要做的操作:支持撤回并需要画反向边 这个算法在G中有环依旧可行
Analysis¶
T = \(O( f |E|)\) where f is the maximum flow. $$ T = T_{augmentation} * T_{find a path}$$ $$ = O( |E| log_{capmax} ) * O( |E| log |V| )$$ $$ = O( |E|^2 log |V| ) $$
六、Minimum Spanning Tree最小生成树¶
概念¶
生成树¶
【Definition】 A spanning tree of a graph G is a tree which consists of V( G ) and a subset of E( G ) 这说明顶点和边都为原图中存在的
一些性质
- 如果存在spanning tree 那原图一定是联通的
- spanning tree不唯一
- 仅有n-1条边,这是树的性质。
- 无环
最小生成树MST¶
生成树中权重和最小的一个,也有可能是不唯一的
算法¶
Prim’s Algorithm¶
类似于 求最小路
Kruskal’s Algorithm¶
- 使用堆,把每个权重丢进去
- 每次取最小;
- 判断是否形成cycle,如果不是就加进去,如果是就丢掉这条边
判断是否是cycle的时候必须要使用并查集
void Kruskal ( Graph G )
{
T = { } ;
while ( T contains less than |V| -1 edges && E is not empty )
{
choose a least cost edge (v, w) from E ;
delete (v, w) from E ;
if ( (v, w) does not create a cycle in T )
add (v, w) to T ;// Union / Find
else
discard (v, w) ;
}
if ( T contains fewer than |V| -1 edges )
Error ( “No spanning tree” ) ;
}
七、DFS深度优先遍历¶
深度优先遍历算法
无向图找联通单元¶
void ListComponents ( Graph G )
{ for ( each V in G )
if ( !visited[ V ] ) {
DFS( V );
printf(“\n“);
}
}
双联通性¶
Articulation point关节点
定义¶
- v is an articulation point if G’ = DeleteVertex(G, v) has at least 2 connected components.
- G is a biconnected graph if G is connected and has no articulation points.
- A biconnected component is a maximal biconnected subgraph.
找关节点¶
- 用深度优先生成一个深度优先树,标出深度优先访问顺序
- 虚线画出回边(back edges)
- 对根节点:查看有几个孩子,超过一个就行;对叶结点, 直接不考虑;对其他,需要它不能在向下走的时候碰到回边。
性质
深度优先树中祖先的深度顺序一定小于孩子的深度顺序,后文我们用这个性质来进行程序的实现
程序实现¶
Low(u)
对非根非叶结点:要求Low(child)>=Num(u),就是一个关节点(这说明它的下方没有路径通向它上方)
Euler Circuits欧拉环¶
欧拉路径与欧拉环
要求条件
- 欧拉回路定理与欧拉路径定理
- 可以用深度优先搜索找到路径
题目¶
1.For a graph, if each vertex has an even degree or only two vertexes have odd degree, we can find a cycle that visits every edge exactly once 错误