Unverified Commit 60755241 authored by ir1d's avatar ir1d Committed by GitHub
Browse files

Merge pull request #921 from 24OI/ir1d/graph

Ir1d/graph
parents 0f9e2f89 03773c45
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@

首先我们称某次询问中被选中的点为——**「关键点」**

设 $Dp[i]$ 表示——使 $i$ 不与其子树中任意一个关键点通的**最小代价**
设 $Dp[i]$ 表示——使 $i$ 不与其子树中任意一个关键点通的**最小代价**

设 $w[a,b]$ 表示 $a$ 与 $b$ 之间的边的权值。

+42 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@

那么什么是前向星呢?事先把 `edge` 数组排个序即可。这里可以使用[基数排序](/basic/sort)做到 $O(m)$ 。

## 一些跟图有关的定义
## 图的基本概念

### 路径

@@ -78,6 +78,14 @@ cycle,也称为 `环` ,是起点和终点相同的路径。

有向图 $G$ 弱连通是指, $G$ 中的所有边替换为无向边后, $G$ 为连通图。

### 点连通度

一张图的点连通度的大小等于最小点割集的大小。

### 边连通度

一张图的边连通度的大小等于最小边割集的大小。

### 子图

选取一个节点的子集和边的子集构成的图。
@@ -114,7 +122,19 @@ cycle,也称为 `环` ,是起点和终点相同的路径。

### 完全图

 $m = \frac{n(n-1)}{2}$ 的简单无向图。
设 $D$ 为 $n (n \geq 1)$ 阶无向简单图,弱 $G$ 中每个顶点均与其余的 $n-1$ 个顶点相邻,则称 $D$ 为 $n$ 阶无向完全图。

无向完全图的点数和边数满足这样的关系: $m = \frac{n(n-1)}{2}$ 。

设 $D$ 为 $n (n \geq 1)$ 阶有向简单图,若对于任意的 $v_i, v_j \in V(D)(v_i \neq v_j)$ ,有向边 $<v_i, v_j>$ 和 $<v_j, v_i>$ 均属于 $E(D)$ ,则称 $D$ 为 $n$ 阶有向完全图。

### 竞赛图

设 $D$ 为 $n (n \geq 1)$ 阶有向简单图,若对于任意的 $v_i, v_j \in V(D)(v_i \neq v_j)$ ,有向边 $<v_i, v_j>$ 和 $<v_j, v_i>$ 中有且仅有一个属于 $E(D)$ ,则称 $D$ 为 $n$ 阶竞赛图。

### 正则图

各顶点的度均相同的无向简单图。

### 路径的长度

@@ -125,3 +145,23 @@ cycle,也称为 `环` ,是起点和终点相同的路径。
两个节点之间,长度最小的路径。

【注】:不一定存在,不一定唯一。

### 图论基本定理

又称握手定理。设 $G=<V, E>$ 为一个无向图, $V= \{v_1, v_2, \cdots, v_n\}, |E| = m$ ,则 $\sum_{i=1}^n{d(v_i)}=2m$ 。其中 $d(v)$ 表示 v 的度数。

### 可图化

如果给定一个序列 a,可以找到一个图 G,以其为度数列,则称 a 是可图化的。

如果给定一个序列 a,可以找到一个简单图 G,以其为度数列,则称 a 是可简单图化的。

#### 判别法

 $a=(a_1, a_2, \cdots, a_n)$ 可图化当且仅当 $\sum_{i=1}^n{d_i} = 0 \pmod 2$ 

 $a=(a_1, a_2, \cdots, a_n)$ 可简单图化当且仅当 $a'=(a_2 - 1, a_3 - 1, \cdots, a_{a_1+1} - 1, a_{a_1+2} - 1, \cdots, a_n)$ 是可简单图化的。

### Whitney 定理

对任意的图 $G$ ,有 $\kappa \leq \lambda \leq \delta$ 。其中 $\kappa, \lambda, \delta$ 分别为 $G$ 的点连通度,边连通度和最小度。
+15 −13
Original line number Diff line number Diff line
@@ -2,25 +2,27 @@

在阅读下列内容之前,请务必了解[图论基础](/graph/basic)部分。

相关阅读:[割点和桥](/graph/bridge/)

## 定义

在一张通的无向图中,如果将一条边删去后,原图变成不通的两部分,我们就说这条边是**桥**
在一张通的无向图中,如果将一条边删去后,原图变成不通的两部分,我们就说这条边是**桥**

在一张通的无向图中,如果将一个点删去后,原图变成不通的两部分,我们就说这个点是**割点**
在一张通的无向图中,如果将一个点删去后,原图变成不通的两部分,我们就说这个点是**割点**

在一张通的无向图中,对于两个点 $u$ 和 $v$ ,如果无论删去哪条边(只能删去一条)都不能使它们不通,我们就说 $u$ 和 $v$ **边双通**
在一张通的无向图中,对于两个点 $u$ 和 $v$ ,如果无论删去哪条边(只能删去一条)都不能使它们不通,我们就说 $u$ 和 $v$ **边双通**

在一张通的无向图中,对于两个点 $u$ 和 $v$ ,如果无论删去哪个点(只能删去一个,且不能删 $u$ 和 $v$ 自己)都不能使它们不通,我们就说 $u$ 和 $v$ **点双通**
在一张通的无向图中,对于两个点 $u$ 和 $v$ ,如果无论删去哪个点(只能删去一个,且不能删 $u$ 和 $v$ 自己)都不能使它们不通,我们就说 $u$ 和 $v$ **点双通**

边双通具有传递性,即,若 $x,y$ 边双通, $y,z$ 边双通,则 $x,z$ 边双通。
边双通具有传递性,即,若 $x,y$ 边双通, $y,z$ 边双通,则 $x,z$ 边双通。

点双**不**具有传递性,反例如下图, $A,B$ 点双通, $B,C$ 点双通,而 $A,C$ **不**点双通。
点双**不**具有传递性,反例如下图, $A,B$ 点双通, $B,C$ 点双通,而 $A,C$ **不**点双通。

![bcc-counterexample.png](images/bcc-counterexample.png)

## DFS

对于一张通的无向图,我们可以从任意一点开始 DFS,得到原图的一棵生成树(以开始 DFS 的那个点为根),这棵生成树上的边称作**树边**,不在生成树上的边称作**非树边**
对于一张通的无向图,我们可以从任意一点开始 DFS,得到原图的一棵生成树(以开始 DFS 的那个点为根),这棵生成树上的边称作**树边**,不在生成树上的边称作**非树边**

由于 DFS 的性质,我们可以保证所有非树边连接的两个点在生成树上都满足其中一个是另一个的祖先。

@@ -34,7 +36,7 @@ void DFS(int p) {
}
```

## DFS 找桥并判断边双
## DFS 找桥并判断边双

首先,对原图进行 DFS。

@@ -48,16 +50,16 @@ void DFS(int p) {

怎么优化呢?可以用差分。对于每一条非树边,在其树上深度较小的点处打上 `-1` 标记,在其树上深度较大的点处打上 `+1` 标记。然后 $O(n)$ 求出每个点的子树内部的标记之和。对于一个点 $u$ ,其子树内部的标记之和等于覆盖了 $u$ 和 $u$ 的父亲之间的树边的非树边数量。若这个值非 $0$ ,则 $u$ 和 $u$ 的父亲之间的树边不是桥,否则是桥。

用以上的方法 $O(n+m)$ 求出每条边分别是否是桥后,两个点是边双通的,当且仅当它们的树上路径中**不**包含桥。
用以上的方法 $O(n+m)$ 求出每条边分别是否是桥后,两个点是边双通的,当且仅当它们的树上路径中**不**包含桥。

## DFS 找割点并判断点双
## DFS 找割点并判断点双

![bcc-2.png](images/bcc-2.png)

如上图所示,黑色边为树边,红色边为非树边。每一条非树边连接的两个点都对应了树上的一条简单路径。

考虑一张新图,新图中的每一个点对应原图中的每一条树边(在上图中用蓝色点表示)。对于原图中的每一条非树边,将这条非树边对应的树上简单路径中的所有边在新图中对应的蓝点连成一个通块(这在上图中也用蓝色的边体现出来了)。
考虑一张新图,新图中的每一个点对应原图中的每一条树边(在上图中用蓝色点表示)。对于原图中的每一条非树边,将这条非树边对应的树上简单路径中的所有边在新图中对应的蓝点连成一个通块(这在上图中也用蓝色的边体现出来了)。

这样,一个点不是桥,当且仅当与其相连的所有边在新图中对应的蓝点都属于同一个通块。两个点点双通,当且仅当它们在原图的树上路径中的所有边在新图中对应的蓝点都属于同一个通块。
这样,一个点不是桥,当且仅当与其相连的所有边在新图中对应的蓝点都属于同一个通块。两个点点双通,当且仅当它们在原图的树上路径中的所有边在新图中对应的蓝点都属于同一个通块。

蓝点间的连通关系可以用与求边双通时用到的差分类似的方法维护,时间复杂度 $O(n+m)$ 。
蓝点间的连通关系可以用与求边双通时用到的差分类似的方法维护,时间复杂度 $O(n+m)$ 。
+5 −1
Original line number Diff line number Diff line
## 定义

二分图英文名叫 Bipartite graph。
二分图,又称二部图,英文名叫 Bipartite graph。

二分图是什么?节点由两个集合组成,且两个集合内部没有边的图。

@@ -31,6 +31,10 @@

### 二分图匹配

#### 霍尔定理

设二部图 $G=<V_1, V_2, E>, |V_1| \leq |V_2|$ ,则 $G$ 中存在 $V_1$ 到 $V_2$ 的完备匹配当且仅当对于任意的 $S \subset V_1$ ,均有 $|S|\leq|N(S)|$ ,其中 $N(S)=\Cup_{v_i \in S}{N(V_i)}$ ,是 $S$ 的邻域。

#### 最大匹配

#### 最大权匹配
+5 −5
Original line number Diff line number Diff line
相关阅读:[通分量](/graph/bcc/)
相关阅读:[通分量](/graph/bcc/)

## 割点

> 如果在一个图中,如果把一个点删除,那么这个图不再通,那么这个点就是割点(割顶),当然是在无向图。
> 如果在一个图中,如果把一个点删除,那么这个图不再通,那么这个点就是割点(割顶),当然是在无向图。

### 如何实现?

如果我们尝试删除每个点,并且判断这个图的通性,那么复杂度会特别的高。所以要介绍一个常用的算法: $Tarjan$ 。
如果我们尝试删除每个点,并且判断这个图的通性,那么复杂度会特别的高。所以要介绍一个常用的算法: $Tarjan$ 。

首先,我们上一个图:

@@ -98,7 +98,7 @@ int main() {
    edge[x].push_back(y);
    edge[y].push_back(x);
  }                             // 使用 vector 存图
  for (int i = 1; i <= n; i++)  // 因为 Tarjan 图不一定
  for (int i = 1; i <= n; i++)  // 因为 Tarjan 图不一定
    if (!vis[i]) {
      inde = 0;      // 时间戳初始为 0
      Tarjan(i, i);  // 从第 i 个点开始,父亲为自己
@@ -115,7 +115,7 @@ int main() {

和割点差不多,还叫做割桥。

> 无向通图中,去掉一条边,图中的连通分量数增加,则这条边,称为桥或者割边,当然也是在无向图。
> 无向通图中,去掉一条边,图中的连通分量数增加,则这条边,称为桥或者割边,当然也是在无向图。

### 实现

Loading