学习笔记第五十一节:图论相关

正题

      因为图论的东西太多,太杂,就懒得用很多篇blog来写,以免被别人说水blog

      这个blog要讲的东西有:

  1. 割点与割边
  2. 点双与边双联通分量
  3. 圆方树
  4. 欧拉通路,欧拉回路

      看到身后的wsh大佬学习了上面这些东西,想想发现自己啥都不会,就赶紧来学了。

      有向图强连通分量

      首先我们要理解Tarjan求解有向图强连通分量的那套理论。因为如果这套理论搞懂了就很好理解下面的步骤了。

      我们开两个数组low,dfn。dfn表示i点的dfs序,low表示i点能到达的最小的dfs序。

      有两个步骤:

  1. 若存在边(x,y),且y未被遍历,那么遍历y,然后用low[y]更新low[x]
  2. 若存在边(x,y),且y被遍历过,那么用low[y]更新low[x],也可以用dfn[y]更新low[x](个人理解前者正确)

      暂时没有找到人会证明low[y]更新low[x]是错的。

      下面的都属于无向图

      割点

      首先dfs树上一个点的两个子树没有一条直接边相连(也就是没有横叉边),否则在遍历第一个会直接遍历第二个子树。

      割点在第二个步骤里面只可以用dfn[y]更新low[x],因为此时的low[x]的定义发生改变,变为dfs到x的这条链上x能到达的最上面那个点。其次不能走父亲那条边。

      根要特殊判断,若根有两个dfs树上两个节点,那么说明割掉根会形成两个联通块,那么根就是一个割点,否则不是。

      对于一个点,如果有dfs树上y是x的儿子,而且low[y]>=dfn[x],那么说明y不能走到x的祖先去,也就说明了割掉x,会出现y这个联通块,因为无向图遍历的时候无横叉边,只有返祖边和前向边会遍历到一个已经遍历的点。

      割边

      更新方法还是一样的。

      根也不用特殊判断,若(x,y)是树枝边,low[y]>dfn[x],那么说明y子树内不可以到达x上面的点,说明(x,y)就是一条割边。

      点双联通分量

      对于一个树枝边(x,y),有low[y]==dfn[x],那么说明y子树当前没有被弹出栈的节点low都=dfn[x],否则就会被弹出栈。

      若有两点一边的情况,那么low[y]>dfn[x],所以我们可以直接判断low[y]>=dfn[x],因为不存在一个非两点一边的情况low>dfn[x]。

      仔细想一想吧,这个我已经尽力说清楚了。

      一个点是可能存在于多个点双连通分量里面,所以对于x单独加进集合里面即可,并把栈内的节点弹出来并且加入集合中。

      边双联通分量

      我们把割边删除,然后直接dfs一遍,在一个连通分量里面的肯定就是边双联通分量,因为里面不存在桥了。

      圆方树

      在上面的点双连通分量里面我们已经知道了一个点可能在多个点双连通分量里面。

      那么我们每一个点双连通分量新建一个方点,然后方点向那些在栈内里面的节点连边,x向这个新建的节点连边,我们把原来的这些点称为圆点,那么容易发现圆点和方点是两两相间的,就形成了一棵圆方树,可以用这个东西在上面维护信息。

      特别是仙人掌。

你可能感兴趣的:(学习笔记)