先明白一些概念。
割点:若一个点删除后(也就是与之相连的边统统去掉),无向图不再连通,那么此点称为割点。
桥:若一条边断去后,无向图不再连通,那么此边称为桥。桥有一个很好的性质,就是DFS一个无向图,那么这个过程必定要经过桥。
块:没有割点的无向图称为2-连通分支,也称作块。
割点、桥均可以在DFS的过程中求得。
那么,对于一个无向图有以下操作:
1.将一个无向图的块缩成一个点。这个时候要注意,一个点是有可能在两个块之中的,因此不能用floodfill来求块,也不能仅用一个一维数组标记某点在哪个块之中。其中一种正确的方法是在DFS时使用一个辅助栈,每次访问一个节点时将该节点进栈,在遇到割点的时候将栈内的元素退栈,直到退到当前节点。那么这一次退出来的节点,再加上当前割点,必定就是一个块。
2.很多人说的“缩点”,其实并不是指缩块。而是指将无向图中没有割边的子图缩成一个点。这样缩点之后图就会变成一棵树,树上的边必定是一条桥。此外,如果这样缩点,那么一个节点只能在其中的一个“块”内。这个道理很明显,一个桥若断开,就把图分成不连通的两部分。一个点不可能同时在这两个部分中。
这个缩点的方法很多,既可以像上面那样,在DFS的时候用栈处理,也可以在DFS后将图上的桥断开,然后floodfill。不过这个方法虽然容易理解,但似乎只能用在邻接矩阵中,而且复杂度比较高。
处理问题的时候必须先弄清楚题目的意思,题目要求的是点的连通性,还是边的连通性。根据要求我们再去“缩点”,“缩块”。举个例子:某网络中由服务器和网线组成,问哪些服务器瘫痪后,整个网络就被隔开,不能通信,这个明显问的就是割点。但是,如果问题改成,如果哪些网线断开后,整个网络就不能通信,那么这个问的就是桥。
下面举一些POJ的题目作为例子:
POJ 2942 - Knights of the Round Table
这个题就是明显的缩块。
POJ 1523 - SPF
这个应该是点连通性
POJ 3177 - Redundant Paths
POJ 3352 - Road Construction
POJ 3694 - Network
这三个题目都是关于边连通性
有向图的连通性
强连通:对于一个图G中任意的两个节点u与v,如果都存在一条u到v与v到u的路径,那么则称此图为强连通图。
非连通图的极大强连通子图称为强联通分量。
有向图缩点:也就是把所有强联通分量缩成一个点后构成的新图。缩点的算法为Kosaraju和Tarjan算法。
Kosaraju需要两次DFS,但是比较容易理解,Tarjan似乎是一次DFS,本人没有接触过。个人认为,在竞赛中,Kosaraju算法实现简单,比较实用。Kosaraju怕的不是大数据,而是多数据。因为如果数据规模大,那么无论是Kosaraju,还是Tarjan,只要写成递归的都会爆栈。这样一次DFS和两次DFS也就没有区别了。
有向图缩点的题目很多,比较经典的如下:
POJ 1236 - Network of Schools
所谓的“最小点基”。
有向图缩点一个很大的应用,就是2-SAT问题。如:
POJ 3678 - Katu Puzzle
POJ 3683 - Priest John's Busiest Day
这类问题比较多。
总结一下:
我所知道的”缩点“就是三种:
无向图缩块(缩无割点子图)
无向图缩无割边子图
有向图缩强连通分量
先明白一些概念。
割点:若一个点删除后(也就是与之相连的边统统去掉),无向图不再连通,那么此点称为割点。
桥:若一条边断去后,无向图不再连通,那么此边称为桥。桥有一个很好的性质,就是DFS一个无向图,那么这个过程必定要经过桥。
块:没有割点的无向图称为2-连通分支,也称作块。
割点、桥均可以在DFS的过程中求得。
那么,对于一个无向图有以下操作:
1.将一个无向图的块缩成一个点。这个时候要注意,一个点是有可能在两个块之中的,因此不能用floodfill来求块,也不能仅用一个一维数组标记某点在哪个块之中。其中一种正确的方法是在DFS时使用一个辅助栈,每次访问一个节点时将该节点进栈,在遇到割点的时候将栈内的元素退栈,直到退到当前节点。那么这一次退出来的节点,再加上当前割点,必定就是一个块。
2.很多人说的“缩点”,其实并不是指缩块。而是指将无向图中没有割边的子图缩成一个点。这样缩点之后图就会变成一棵树,树上的边必定是一条桥。此外,如果这样缩点,那么一个节点只能在其中的一个“块”内。这个道理很明显,一个桥若断开,就把图分成不连通的两部分。一个点不可能同时在这两个部分中。
这个缩点的方法很多,既可以像上面那样,在DFS的时候用栈处理,也可以在DFS后将图上的桥断开,然后floodfill。不过这个方法虽然容易理解,但似乎只能用在邻接矩阵中,而且复杂度比较高。
处理问题的时候必须先弄清楚题目的意思,题目要求的是点的连通性,还是边的连通性。根据要求我们再去“缩点”,“缩块”。举个例子:某网络中由服务器和网线组成,问哪些服务器瘫痪后,整个网络就被隔开,不能通信,这个明显问的就是割点。但是,如果问题改成,如果哪些网线断开后,整个网络就不能通信,那么这个问的就是桥。
下面举一些POJ的题目作为例子:
POJ 2942 - Knights of the Round Table
这个题就是明显的缩块。
POJ 1523 - SPF
这个应该是点连通性
POJ 3177 - Redundant Paths
POJ 3352 - Road Construction
POJ 3694 - Network
这三个题目都是关于边连通性
有向图的连通性
强连通:对于一个图G中任意的两个节点u与v,如果都存在一条u到v与v到u的路径,那么则称此图为强连通图。
非连通图的极大强连通子图称为强联通分量。
有向图缩点:也就是把所有强联通分量缩成一个点后构成的新图。缩点的算法为Kosaraju和Tarjan算法。
Kosaraju需要两次DFS,但是比较容易理解,Tarjan似乎是一次DFS,本人没有接触过。个人认为,在竞赛中,Kosaraju算法实现简单,比较实用。Kosaraju怕的不是大数据,而是多数据。因为如果数据规模大,那么无论是Kosaraju,还是Tarjan,只要写成递归的都会爆栈。这样一次DFS和两次DFS也就没有区别了。
有向图缩点的题目很多,比较经典的如下:
POJ 1236 - Network of Schools
所谓的“最小点基”。
有向图缩点一个很大的应用,就是2-SAT问题。如:
POJ 3678 - Katu Puzzle
POJ 3683 - Priest John's Busiest Day
这类问题比较多。
总结一下:
我所知道的”缩点“就是三种:
无向图缩块(缩无割点子图)
无向图缩无割边子图
有向图缩强连通分量