• 图论


      经典的七桥问题:

      问怎样走能经过所有的桥并且每个桥只经过一次;

      

      开始并不知道第二个图是怎么到的第三个图,然后某zz是这么说的;

      

      所以就是这样了;

      然后又是经典的国际象棋问题:

      国际象棋棋盘为8*8期盼,但我们一般是要扩展到n*m的,然后就要知道,马在棋盘上是怎么走的呢?

      Δx=1,Δy=2或者Δx=2,Δy=1;当然可能我们一般理解或者做题的时候,是在格点上操作的,

      但应该要转化到格子上去理解和操作,如图:

      

      然后要说的就是,nm取值的影响了,首先nm都是奇数,则无法构成回路(不能回到原来的位置);

      当n==1时,则无法完成移动步数为2的情况,所以无解;

      当n==2时,

      

      很明显所能到达的点的列数必定与初始所在列数奇偶性相同;

      当n==4时,我们引入黑白染色,红蓝染色这个说法,

      规定如下棋盘: 

      

       很明显途中有四个类型的格子:红黑,红白,蓝黑,蓝白;

      那么它一次能到达的所有可能的格子中,没有一个会是与原来这个格子染色情况相同的,

      如图:

      

      这时我们可以把整个棋盘分成两半,

      一半的染色情况是:红+黑 和 蓝+白,另一半的染色情况是:红+白 和 蓝+黑;

      但我们可以发现这与上图是矛盾的,我们每次走一步的两种情况的可能性并不是1:1,

      所以不能遍历到整个图;

      ……更大的情况略;

    一些图的基本概念  

      节 (结, 顶) 点 (node): 图的基本构成元素, 一般以小写字母表示 (u, v, ...).
      标号: 大部分图论算法是建立在有标号节点之上的.
      边 (edge): 节点对 (u,v). 可分为有向边 (有序节点对) 和无向边 (无序节点对),
      对于有向边, u 称作始点, v 称作终点.
      重边: 相同的边
      自环: (u,u)
      图 (graph): G = (V,E). 其中 V 是点集, E 是可重边集.

      各种图:
      无向图, 有向图, 混合图.
      简单图 (无重边和自环)
      完全图 (K n ), 竞赛图

      DAG:有向无环图;

      补充:完全图:边最多的简单图,可以理解为,任意一对节点之间都有边,像这样

      

      那么竞赛图呢?:就是一个完全图,但是每个边都赋有一个方向,像这样:

      

      权
      边权: w : E → R/N
      点权: w : V → R/N

      度  

      度:边与点的相遇;  
      度: d : V → N, 与某节点相邻的边数.
      正 (出) 度: 以某节点为始点的边数.
      负 (入) 度: 以某节点为终点的边数.

      有根树和无根树度的定义不同,(一个包含所有入度出度,,另一个,,,)

      度的性质:

      

      度为奇数的节点必为偶数个.(只对竞赛图)

      

    图的存储

      

      

      例如上图

      邻接矩阵:a[i][j],(无向图a[j][i]) ,缺点:不能记重边;

      前向星:

      十字链表,如图:

      

      

    查询指定边信息?


      邻接矩阵: O(1)
      前向星: O(E)/O(logE)
      邻接表/十字链表: O(E)/O(logE)

    路径  

      有向路径: P = (e 1 ,...,e n ), 其中 e i 的终点是 e i+1 的始点.
      初等: 路径经过的边两两不同.
      简单: 路径经过的点两两不同 (除路径的始点与终点外).
      环: 路径的始点与终点相同.
      无向图上的路径: 存在一种每一条边分配方向的方案使得其成为一条有向图的路径.

    自由树  

      自由树: 连通的无环无向图.
      森林: 树的集合.

      对于一棵自由树而言, 以下 6 条等价:
      1.G 是一棵自由树.
      2.G 中任何两顶点由唯一简单路径相连.
      3.G 是连通的, 但是从图中移除任意一条边得到的图均不连通.(都是桥)
      4.G 是连通的, 且 |E| = |V| - 1
      5.G 是无环的, 且 |E| = |V| - 1
      6.G 是无环的, 但若向 E 中添加任意一条边, 均会造成该图包含恰有一个环.

    有根树与二叉树  

      有根树: 自由树 + 根.
      节点之间的关系: 父亲与儿子, (真) 祖先与 (真) 后代, 叶节点.
      子树: u 的所有后代的导出子图.
      定义在点集上的函数: 度, 深度, 大小.

      导出子图是什么?
      设V1是V的一个非空子集,以V1为顶点集,
      以两端点均在V1中的边的全体为边集的子图称为G的导出子图.

      

    二叉树:左子树,右子树

      一些性质:  

      任何非空二叉树中,度为2的节点数比叶节点数少1.
      n个节点的二叉树高度至少为 logn(下取整)
      Kraft 不等式: 将二叉树 T 中每个深度为 d 的叶节点赋予权值 w(x) = 2-d,则∑w(x) ≤1.

    树的存储  

      可以保存的信息:
      边信息
      父亲
      儿子
      大部分题会将树作为一个无向图来读入, 也有的题会告诉你某个点的父亲是谁, 保存哪些信息取决于你的需求.

    图的遍历  

      BFS(breadth first search): 求图中两点间最短路径?
      (路径长度被定义为其拥有的边数)
      时间复杂度: O(V + E)
      BFS 生成树
      DFS(depth first search): DFS 生成树.
      边的分类:
      树边
      后向边(指向祖先的边)
      前向边(指向后代的边)
      横向边(既不指向祖先,也不指向后代的边)
      性质:
      括号化定理 ([vl,vr])
      无向图 G 不存在横向边

    联通  

      连通: 若图G的任意两点间均存在路径,则称图G连通.
      子图: 若G'= (V',E') 满足 V'⊆V, E'⊆E, 则称 G'是G的子图.
      导出子图:若E'包含了G在 V'中的所有边,则称 G'是G关于 V 的导出子图.
      (无向图的) 极大连通子图 (连通支): 若 G'满足不存在 H,
      使得 G'是 H 的子图, H 是 G 的子图, 则称 G'是 G 的极大连通子图.

    拓扑排序  

      在DAG(Directed Acyclic Graph,有向无环图)中求一个排列P,
      使得对于每个点v而言,若(u,v)存在,则u在P中在v之前.
      Kahn算法:不断寻找入度为0的点.
      基于DFS的算法:以vr排序.

    欧拉路径: 经过所有边的简单路径.
    欧拉回路: 经过所有边的简单环.

    欧拉路径(环)  

      连通无向图:
      存在欧拉回路 等价于度为奇数的点有 0 个.
      存在欧拉路径 等价于度为奇数的点有 0 或 2 个.
      连通有向图 (边忽略方向后得到的无向图连通):
      存在欧拉回路 等价于所有点出入度相等.
      存在欧拉路径 等价于所有点出入度相等 或恰有一个点
      入度比出度多 1 和恰有 1 个点出度比入度多 1.
      如何求出一条欧拉路径?
      Prop.若G中有k个度为奇数的点,G可以划分为k/2条简单道路.

    最短路

      最短路:有向边权图中两点间的所有路径中最短的一条.(若不连通,定义为 ∞)  

      负权边:负权图的最短路径中可能有无穷多条边.
      环路:不可能包含回路     ;
      松弛操作: d(x,v) = min(d(x,v),d(x,u)+w(u,v))
      三角不等式: d(x,v) ≤d(x,u)+w(u,v)
      最短路径树与最短路径图

     

    Dijkstra  

      算法流程:维护已经找到最短路的点集S,不断地寻找距离S最近的点将其加入S.
      仅适用于边权非负的图.
      时间复杂度:O((V+E)log(V+E))/O((V+E)logV)/O(VlogV+E)

    Bellman-Ford   

    for(int i=n;i;--i)
    	for(int j=m;j;--j)
    		dis[v[j]]=min(dis[v[j]],dis[u[j]]+w[j]); 

      不断在最短路中加边.
      时间复杂度: O(VE)
      SPFA: deprecated
      Hack: 网格图, 次短路条数很多的图.

     Floyd  

    for(int k=n; k; --k)
    	for(int i=n; i; --i)
    		for(int j=n; j; --j)
    			dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);  

      可以看作 DP.
      同时求出每对点间的最短路.
      时间复杂度: O(V^3)

    Johnson  

      每对顶点间的最短距离(稀疏有向图)
      重新赋予权重: w'(u,v)=w(u,v)+d(0,u)-d(0,v)
      一遍 Bellman-Ford+|V|遍Dijkstra.
      时间复杂度: O(V2logV + VE)

    应用: 差分约束系统

        

      若 x = (x1,……,xn) 是差分约束系统的一个解,
      则 x + d 也是差分约束系统的一个解.
      约束图: 新建 0 点, w(0, i)(1 ≤i ≤n) 为 0; w(jl, il) 为 kl.

    强连通分量  

      强连通分量 (SCC, Strongly Connected Component):
      有向图的极大点集 C ⊆ V, C 中任意两点可达.
      Kosaraju 算法: 以 vr 逆序对 GT = (V, ET) 作 DFS,则每棵DFS 树会是一个 SCC.
      Tarjan 算法: 使用一个栈来维护尚未被分到 SCC 中的节点,
      依据一个节点 u 是否能走到其 DFS 树中的祖先 (low(u)),来取出栈中节点分配成一个新的 SCC.
      Gabow 算法: 使用两个栈来取代 low, S 表示尚未被分配的节点, P 表示尚未被分配 SCC 的节点.
      时间复杂度均为 O(V + E)

      将 SCC 缩点, 原图变为 DAG.

    边双连通分量  

      桥 (割边): 删掉之后会导致图不连通的边.
      边双连通分量 (BCC, biconnected component) 的等价定义:

        极大连通导出子图,不含桥.

        极大连通导出子图,使得任意两点间均有两条边不相交路径.

        极大连通导出子图,使得任意两条边都存在于一个简单回路中.

        极大连通导出子图,任意三点 a, b, c, 存在边不相交的路径 a → b, b →c.

        极大连通导出子图,存在一种给边赋向的方案使得其为SCC.

      判断割边: low(u) = ul

      将 BCC 缩点, 原图变为树.

    点双连通分量  

      割点: 删掉之后会导致图不连通的点.
      点双连通分量 (块, block) 的等价定义:

           极大连通导出子图,删除其中任意一个点不会使其不连通.

        极大连通导出子图,任意两个点之间有两条点不相交路径.

        极大连通导出子图,任意三点 a, b, c 之间, 两条点不相交路径.

      注意到两个块可以有至多一个交点.

      割点的等价条件:

        根节点是割点当且仅当其DFS树至少有两个子树.

        非根节点是割点当且仅当 low(u) < ul.

      将 Block 缩成环, 原图变为仙人掌.

    最小生成树基本概念:环与割  

      切割: (S, V -- S), 对 V 的一个划分.
       横跨: (u, v) 一个端点在 S, 另一个端点在 V -- S, 则称 (u, v)横跨割 (S, V -- S).
       尊重: 边集 A 中不存在横跨割 (S, V - S) 的边, 则称(S, V -- S) 尊重 A.
       轻量级边: (u, v) 是横跨 (S, V -- S) 的所有边中权重最小的.

    MST 基本定理   

      对于任意 A ⊆ E, 存在 G 的最小生成树 T, A ⊆ T, 任意e = (u, v) ∈ A,
       存在尊重 A 的切割 (S, V -- S), (u, v) 是(S, V -- S) 的一条轻量级边,
       令 B = A ∪ (u, v), 则存在最小生成树 T', B ⊆ T'.(这条边被称作安全边)

    MST 的求解算法    

        Prim 算法: 类似于 BFS/Dijkstra, 维护一个连通的 A, 不断寻找 (A, S -- A) 中的轻量级边.
      时间复杂度: O((V + E)logV) / O(VlogV + E)
      Kruskal 算法: 从小到大枚举每条边 (u, v), 若 u 和 v 在 A 中尚不连通, 就将 (u, v) 加入 A.
      时间复杂度: O(V + E log E)
      Boruvka 算法: 找到每个点的最小邻边, 形成了环套树森林,将每一个环套树缩点.
      时间复杂度: O((V + E)logV)

    MST 的性质  

        若图 G 的一条边 (u, v) 在某棵最小生成树 T 中,则该条边是某个切割 (S, V -- S) 的轻量级边.
      任意两棵最小生成树的有序边权序列相同.
      对于非负边权图, MST 等价于权值和最小的边集, 使得图连通.
      MST 是瓶颈生成树 (最大边权最小的生成树).

     最近公共祖先:LCA问题  

      LCA(Lowest Common Ancestor, 最近公共祖先):
      LCA(u,v) 定义为 u 和 v 的所有公共祖先中深度最大的那一个.

      倍增: fa[u][j] 表示从 u 向上跳 2^j 步可以到达的点.
      时间复杂度: O(n log n) -- O(log n)

      树链剖分: 重儿子是所有儿子中 size 最大的那个.
      时间复杂度: O(n) -- O(log n)

      DFS 序 +ST: 利用 DFS 序的性质将问题转化为求区间最小值, 再使用 Sparse Table 求解.
      时间复杂度: O(n log n) -- O(1)

      Tarjan: 离线查询, 使用并查集维护当前栈中节点已经遍历过的子树.
      时间复杂度: O(n + m)

    与 RMQ 问题的联系  

      RMQ(Range Minimum/Maximum Query): 查询区间最值.

      静态: ST(Sparse Table)(O(n log n) -- O(1)).
      动态: 线段树 (O(n) -- O(log n)).

      从 LCA 到 RMQ: 利用 DFS 序.(特殊的 ±1 RMQ)
      从 RMQ 到 LCA: 利用笛卡尔树.

      在线查询的线性做法: 以 log n/2 为大小分块, 再使用 Sparse Table.
      时间复杂度: O(n) -- O(1)

  • 相关阅读:
    Shell 学习笔记之函数
    Shell 学习笔记之条件语句
    Shell 学习笔记之运算符
    Shell 学习笔记之变量
    [LeetCode] Zuma Game 题解
    [LeetCode] Decode String 题解
    [LeetCode] Pacific Atlantic Water Flow 题解
    TCP的建立和终止 图解
    [LeetCode] 01 Matrix 题解
    java中protect属性用法总结
  • 原文地址:https://www.cnblogs.com/Mary-Sue/p/9741036.html
Copyright © 2020-2023  润新知