tags: Combinatorics GT
写在前面
最近开始更新图论笔记系列, 没办法做到面面俱到了, 就把自己觉得重要的内容放上来, 有任何问题欢迎大家指正.
主要概念
- 图(graph): 关系的数学表达, 由两个集合: 非空结点集 V V V和有限的边集 E E E组成.
- 图的阶(order): 集合 V ( G ) V(G) V(G)的基数(势) n n n.
- 图的规模(size): 集合 E ( G ) E(G) E(G)的基数 m m m.
- 邻接(adjacent): 指两个节点之间有边连接.
- 关联(incident): 边与左右两个节点关联.
- 结点的度(degree): 与结点相邻接的结点数.
- 孤立点: 度为 0 0 0的结点.
- 最小度: 图中所有结点的最小度数, 记为 δ ( G ) \delta(G) δ(G).
- 最大度: 图中所有结点的最大度数, 记为 Δ ( G ) \Delta(G) Δ(G).
- 正则图(regular graph): 若图中所有结点有相同的度数, 则 δ ( G ) = Δ ( G ) \delta(G)=\Delta(G) δ(G)=Δ(G).
- r − r- r−正则图: 图中所有结点度都为 r r r.
- u − v u-v u−v通道(途径, walk): 指从结点 u u u出发, 经过一个交互的结点和边的序列, 最后回到结点 v v v的路径, 其中连续的结点和边是相关联的.
- 通道的长度: 经过边的数量, 结点和边可以重复.
- 迹(trail): 没有重复边的通道, 结点可以重复.
- 路(路径, path): 结点都不相同的迹.
- 回路(圈, cycle): 即封闭的路径(闭路, closed path), 由于结点不同则边一定不同, 所以回路也可以称为闭迹(closed trail).
- u − v u-v u−v路: 将 u u u和 v v v连接起来的路.
- 连通图(connected graph): 图中任意两个结点之间都存在路.
- 测地线路(测地线, 最短路): 长度最短的 u − v u-v u−v路.
- 子图: H H H结点集与边集都为 G G G的结点集和边集的子集, 且对 H H H中任意一条边, 其两个节点都在结点集 V ( H ) V(H) V(H)中. G G G称为 H H H的超图.
- 连通分量(connected component): 极大连通子图.
- 生成子图(spanning subgraph): V ( H ) = V ( G ) V(H)=V(G) V(H)=V(G).
- 导出子图(induced subgraph): 子图边集中包含了 G G G中连接子图点集的所有边.
- 完全图(complete graph): 所有结点对都邻接. 具有 n n n个结点的完全图记为 K n K_n Kn.
- 平凡图(trivial graph): K 1 K_1 K1.
- 圈(circle): 含有 n n n个结点的圈记为 C n C_n Cn.
- 路(path): 含有 n n n个结点的路记为 P n P_n Pn, 并且满足 P i = K 1 , P 2 = K 2 P_i=K_1, P_2=K_2 Pi=K1,P2=K2.
- 完全二分图(complete bipartite graph): 记为 K m , n K_{m,n} Km,n, 是指图的结点集可以分成两个非空集合 A , B A,B A,B, 分别含有 m , n m,n m,n个结点, A A A中每个结点均要与 B B B中每个结点相关联,且都只与 B B B中结点相关联.
- 星: 只有一个结点度为 n n n, 其余 n n n个结点度为 1 1 1的完全二分图, 记为 K 1 , n K_{1,n} K1,n.
图同构
- 图同构: 图 G G G中结点 u v uv uv邻接当前节点它们在图 H H H中相应的结点也邻接, 记为 G ≅ H G\cong H G≅H. 图同构则节点的度一定相同.
- 度序列: 含有 n n n个结点图 G G G的度序列指按照结点度数排列的 n − n- n−元非递增序列. 有相同度序列的两图不一定同构.
- 可绘图序列: 可以表示某个图的非负整数的非递增序列.
- 可绘图序列的必要条件: 度数之和为偶数.
可绘图序列的判定算法
- 序列 S S S中删除第1个数 k k k.
- 如果 S S S的第一个数后的 k k k个数都大等1, 则将这 k k k个数分别都减去1得到新序列 S ′ S' S′; 否则停止, 得出原序列不绘图. 若 S ′ S' S′全是 0 0 0, 停止, 得到原序列可绘图.
- 将2得到的序列 S ′ S' S′重新排列, 得到非增序列 S ∗ S^* S∗.
- 令 S = S ∗ S=S^* S=S∗,转步骤1.
直接根据上述算法进行判断, 下面给出Python以及C++代码:
S1 = [3, 2, 2, 1, 1, 1]
S2 = [5, 4, 4, 3, 3, 3, 3, 2, 2, 1]
S3 = [7, 7, 4, 3, 3, 3, 2, 1]
S4 = [6, 5, 4, 3, 3, 3, 2, 0]
def isGraphic(S):
if len(S) == 0 or sum(S) % 2 == 1:
return False
# 只要不是全0序列, 就进入循环
while S.count(0) != len(S):
k = S.pop(0)
if k <= len(S):
for i in range(k):
if S[i] >= 1:
S[i] -= 1
else:
return False
S.sort(reverse=True)
else:
return False
return True
print(isGraphic(S1))
print(isGraphic(S2))
print(isGraphic(S3))
print(isGraphic(S4))
"""
True
True
False
True
"""
对于python代码, 用到了一些列表操作的内置函数, 进一步优化可以得到下面的代码:
def isGraphic(S):
if len(S) == 0 or sum(S) % 2 == 1:
return False
# 只要不是全0序列, 就进入循环
while S[0] != 0:
k = S.pop(0)
if k <= len(S):
for i in range(k):
if S[i] >= 1:
S[i] -= 1
else:
return False
S.sort(reverse=True)
return True
// C++代码实现
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;
bool isGraphic(vector<int> &S) {
if (S.size() == 0 || accumulate(S.begin(), S.end(), 0) % 2 == 1)
{
return false;
}
while(S[0] != 0) {
int k = S[0];
S.erase(S.begin());
if (k <= S.size())
for (int i=0;i<k;i++) {
if (S[i] >= 1)
S[i]--;
else
return false;
}
sort(S.rbegin(), S.rend());
}
return true;
}
int main(int argc, char const *argv[])
{
vector<int> S1 = {3, 2, 2, 1, 1, 1},
S2 = {5, 4, 4, 3, 3, 3, 3, 2, 2, 1},
S3 = {7, 7, 4, 3, 3, 3, 2, 1},
S4 = {6, 5, 4, 3, 3, 3, 2, 0};
cout<<isGraphic(S1)<<endl;
cout<<isGraphic(S2)<<endl;
cout<<isGraphic(S3)<<endl;
cout<<isGraphic(S4)<<endl;
return 0;
}
图的基本操作
并与和
两个图的并必须是不相交的, 对于图 G G G和 H H H, 有
G ∪ H : { V ( G ∪ H ) = V ( G ) ∪ V ( H ) E ( G ∪ H ) = E ( G ) ∪ E ( H ) G\cup H:\begin{cases} V(G\cup H)=V(G)\cup V(H)\\[5pt] E(G\cup H)=E(G)\cup E(H)\\ \end{cases} G∪H:⎩⎨⎧V(G∪H)=V(G)∪V(H)E(G∪H)=E(G)∪E(H)
两个不相交图的和 G + H G+H G+H是指在 G ∪ H G\cup H G∪H的基础上, 增加 G G G的每个结点与图 H H H的每个结点相连接得到的边.
边与结点的删除
- 设 v v v是 G G G 的结点, 则 G − v G-v G−v是指从图 G G G 中删除结点 v v v, 并将所有与结点 v v v相关联的边删除.
- 设 e e e是图 G G G 的一条边, 那么 G − e G-e G−e是指从图 G G G 中删除边 e e e.
补图
类比集合的补运算, 图 G G G的补图 G ‾ \overline{G} G满足 V ( G ‾ ) = V ( G ) V(\overline G)=V(G) V(G)=V(G), 并且当且仅当 u v ∉ E ( G ) uv\notin E(G) uv∈/E(G)时, u v ∈ E ( G ‾ ) uv\in E(\overline G) uv∈E(G).
- 自补图: 图 G G G与其补图同构. 自补图 G G G满足阶 n n n可以表示成 4 k 4k 4k或者 4 k + 1 4k+1 4k+1的形式, k k k为非负整数, 并且图 G G G有 n ( n − 1 ) / 4 n(n-1)/4 n(n−1)/4条边.
笛卡尔积
又称叉乘
, 指两个图的结点之间进行笛卡尔积. 满足结合律.
利用笛卡尔积可以定义如下的几种图.
超立方体
递归定义, 可由定义式扩展到高维空间.
Q 1 = K 2 , Q n = K 2 × Q n − 1 . Q_1=K_2,Q_n=K_2\times Q_{n-1}. Q1=K2,Qn=K2×Qn−1.
网格
M ( m , n ) = P m × P n , M ( p , q , r ) = P p × P q × P r . M(m,n)=P_m\times P_n,\\ M(p,q,r)=P_p\times P_q\times P_r. M(m,n)=Pm×Pn,M(p,q,r)=Pp×Pq×Pr.
线图
线图 L ( G ) L(G) L(G)的结点集由原图 G G G边构成, 将原图 G G G结点进行标记之后容易得到线图.
边收缩
设 u v uv uv是 G G G的一条边, 将节点 u , v u,v u,v和与这两个结点相关联的边都去掉, 并添加一个结点 u v ∗ uv^* uv∗, 使得 u v ∗ uv^* uv∗与原结点 u , v u,v u,v相邻接的结点邻接, 记为 G / u v G/uv G/uv.