一、割
引例
学校现在一共拥有N台服务器(编号1..N)以及M条连接,保证了任意两台服务器之间都能够通过连接直接或者间接的数据通讯。
当发生黑客攻击时,学校会立刻切断网络中的一条连接或是立刻关闭一台服务器,使得整个网络被隔离成两个独立的部分。
问:在学校的网络中有哪些连接和哪些点被关闭后,能够使得整个网络被隔离为两个部分
1≤N≤20,000, 1≤M≤100,000
http://hihocoder.com/problemset/problem/1183
下面的例子中,满足条件的有边(3,4),点3和点4。
一堆定义:
割边:在连通图中,删除了连通图的某条边后,图不再连通。这样的边被称为割边,也叫做桥。
割点:在连通图中,删除了连通图的某个点以及与这个点相连的边后,图不再连通。这样的点被称为割点。
DFS搜索树:用DFS对图进行遍历时,按照遍历次序的不同,我们可以得到一棵DFS搜索树。
树边:在搜索树中的蓝色线所示,可理解为在DFS过程中访问未访问节点时所经过的边
回边:在搜索树中的橙色线所示,可理解为在DFS过程中遇到已访问节点时所经过的边
怎么判断一个点是否为割点呢??
有两类节点可以成为割点:
1、对根节点u,若其有两棵或两棵以上的子树,则该根结点u为割点;
(有两颗或以上的子树时,如果去掉根节点,那么从每一个点开始都不会遍历上下的点)
2、对非叶子节点u(非根节点),若其中的某棵子树的节点均没有指向u的祖先节点的回边,
说明删除u之后,根结点与该棵子树的节点不再连通;则节点u为割点。
但是对于非叶子节点,怎么去判断有没有回边?
我们用dfn[u]记录节点u在DFS过程中被遍历到的次序号,low[u]记录节点u或u的子树通过回边追溯到最早
的祖先节点(即DFS次序号最小),那么low[u]的计算过程如上图:
那么我们就能得到一开始那个图的low, 与 dfn数组
那么我们求出了这个low数组 之后,怎么判断是不是一个割点呢??
当(u,v)为树边且low[v]≥dfn[u]时,节点u才为割点。
而当(u,v)为树边且low[v]>dfn[u]时,表示v节点只能通过该边(u,v)与u连通,那么(u,v)即为割边。
那么来看一下求割点与割边的代码吧
二、强连通分量
一些关于强连通分量的定义:
出度: 以顶点v为起点的边的数目。
入度:以顶点v为终点的边的数目。
可达:如果在有向图G中,有一条<u,v>有向道路,则v称为u可达的,或者说,从u可达。
强连通:图中有两点u,v。从u可达v,从v可达u,则称u,v强连通。
强连通图:有向图G的任意两个顶点都互相可达。
强连通分量:非强连通图有向图的极大强连通子图,称为强连通分量。
特别的:强连通图的强连通分量为本身。
依托数据结构:栈
例题:
noip2015 信息传递
练习:
http://hihocoder.com/problemset/problem/1185
三、双连通分量
对于一个无向图的子图,当删除其中任意一条边后,不改变图内点的连通性,
这样的子图叫做边的双连通子图。而当子图的边数达到最大时,叫做边的双连通分量。
对于一个无向图,当我们把图中所有的桥都去掉以后,剩下的每一个区域就是我们要求的边的双连通分量
例题:
http://hihocoder.com/problemset/problem/1184