组合论基础课(Trees)
来源:互联网 发布:明保理和暗保理 知乎 编辑:程序博客网 时间:2024/06/10 21:37
最近在看J. H. van Lint和R. M. Wilson写的A Course in Combinatorics. 这本书每个章节都会介绍一个领域,然后把其中一些non-trivial的定理介绍出来,挺好玩的。这些结论让我彻底明白之前很多模模糊糊的概念。
Trees
定理2.1 对于一个n个节点的图,总共有n^(n-2)个不同的"标签"树。
原文中的“labeled”我不知道如何翻译最好,就直译成“标签”了。说是标签树,那是为了防止算上“同质”树。作者给了三个证明,其中第一个证明最有趣,它的思想就是:如果你要数一个很复杂的空间A的时候,最好就把它映射到一个简单的空间B,你能搞明白B,也就能搞明白A了。
下一个定理是关于最小生成树的。我们考虑对一个图G的每条边都给一个权重c,i.e. 对于边 e_i, c(e_i) 就是它的“cost”,如何找一个生成树T,使得它的cost最小?这个问题是网络里面的经典问题。结果就是“贪心算法”, 就足以完成这个任务。
最小生成树的贪心算法:给定一个连通图G, 和一个待选的边的集合S。一开始S = {},即是空的。重复以下步骤:当S = {e_1, e_2, ..., e_k}的时候,从E - S里面选一个边e_{k+1},使得e_{k+1}连接了两个仍是分离的component,而且e_{k+1}是所有符合上述条件里面的边中cost最小的。
上述算法直观理解很简单,就是一开始有n个节点,它们一条边没有,然后你就一条一条边加回去。由于只有n个节点,一个树只有n-1条边,所以你只需做n-1次操作。每次操作就是把一个孤立的点和某一个component连接起来,选择哪个孤立点呢?就是选择cost最小的边的那个孤立点。 下面的定理2.2就是证明,这个贪心算法找出来的生成树真的是最小生成树
定理2.2 贪心算法找出来的生成树是最小生成树。
证明:对于任意一个生成树T,我们把{a_1, a_2, ..., a_n-1}记为它对应的边的集合,并且按照cost从小到大排序,即是c(a_1) <= c(a_2) <=...<=c(a_{n-1}). 然后对于用贪心算法找出来的生成树我们记为T_0, 以及对应的边的集合{e_1, e_2, ..., e_{n-1}}. 实际上,有一个更强的结论就是c(e_i) <= c(a_i), 就是说,T_0不光在cost的总和赢了,而且每一条边它也赢了。现在来证明c(e_i) <= c(a_i).
如果c(e_i) > c(a_i) >= c(a_{i-1}) >= ... >= c(a_1), 那么贪心算法里面,当做第i次选择的时候,由于这些{a_1, a_2,...,a_i}没有被选上,它们一定是已经各自在某些component里面。当选完e_{i-1}的时候,component的个数为n-i+1, 而现在{a_1,...,a_i}又在这个n-i+1里面,显然是不可能的。为什么呢?因为{a_1, ..., a_i}总共有i条边,那么一定只会造成n-i个component。 证毕。
接下来的内容是关于深度优先和广度优先搜索。以前一直以为深度和广度优先搜索一个树,无非就是写代码上的不同实现方式而已,或者根据一些实际情况用不同的搜索策略,能找的更快点。现在才知道这两个东西是证明许多图的定理的神器。
深度优先搜索法找出来的生成树:一开始随便选一个节点v_0, 然后重复以下步骤:当v_0, v_1,..., v_k以及对应的数T_k被选好了之后,让 m <= k,作为满足v_m连到某个不在T_k的节点的条件中最大的那个m。说白了就是,你要找下一个节点加入当前的T_k,找谁呢?谁有连接到“”外部“节点并且”序号最大“的,就选它,然后把它连的那个”外部节点“作为v_{k+1},而对应的树也变成了T_{k+1}。直到总共找完n个节点为止。
命题2.3 如果x和y在G中是相邻的,那么在任意的深度优先搜索树中,x将会是y的子孙节点或者反过来,y是x的子孙节点。
命题2.4 如果(x, y)是T(G的生成树)的一条边,而且不是”桥“,假设x是y的父节点,那么一定存在一条边(a, b)在G上而不在T上,满足a是y的子孙,b是x的祖先。
Notes: 我们说一个节点x既是x的祖先,也是x的子孙。“桥”是指一条边e,当移除这条边的时候,图G就不连通了。
最后一个定理是关于强连接的有向图。一个有向图D可以从相应的无向图G,在每条边上给定一个方向而产生。
定理2.5 如果G是一个有限的连通图,而且没有“桥”。 那么一定存在一个有向图D由G在每条边上指定方向后产生,并且满足对于任意的两个节点x,y,它们之间存在一个路径。
证明:用深度优先搜索方法找到一个生成树T,对于G上的一条边(v_i, v_j), i < j 根据T的序号,如果(v_i, v_j) 属于T,那么这条边的方向就是v_i --> v_j; 否则,v_j --> v_i. 现在来证明这样的标法能满足定理的条件。实际上,对于v_0, v_i,一定存在一条路径过去,其中v_0是T的根节点。因为我们只要选择那些在T上的边就好了。现在只需证明,v_i能有一条路径走回到v_0那里去。命题2.4表明,一定存在某个在G上而不在T上的边(a, b),使得v_i能走到a那里去(a是v_i的子孙节点),然后a又能走到b那里去,最后b能走到v_i的某个祖宗节点v_k. 从v_k出发,重复这个过程,直到走到v_0为止。证毕。
- 组合论基础课(Trees)
- 组合论基础课(图的染色1)
- 基础课杂记
- Linux基础课
- Java基础课
- 基础课1
- hdu 1294 Rooted Trees Problem 组合数+整数划分
- Unique Binary Search Trees 求BST的组合总数 @LeetCode
- codeforces 9D How many trees? (组合二叉树)
- Unique Binary Search Trees 求BST的组合总数 @LeetCode
- hdu1294 Rooted Trees Problem(重复组合+整数拆分+DFS)
- trees
- ARM第一节基础课
- Prism入门基础课
- 领导者的基础课
- 第一节INTERNET应用基础课
- JAVA基础课总结二
- JAVA基础课总结三
- 四款秋季早餐养生粥大推荐
- 设计模式 - 命令模式(command pattern) 多命令 详解
- PAT1015. 德才论 (25)
- http://793.mrt.ah.cn
- 在物质的时代,真爱的比例还剩多少?
- 组合论基础课(Trees)
- VS编译器优化诱发一个的Bug
- 配置Apache服务器并且设置DNS
- 智能推荐系统开发中的十个关键注意点
- lua弱表引用
- IOS多线程读写Sqlite问题解决
- java.lang.OutOfMemoryError: PermGen space
- 在ruby on rails 中使用kindeditor(2)
- telnet发送http协议-token-json