tarjan【桥、割点、点双、边双、支配树】 Summary
知识点总结
定义
割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点。
割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合。
点连通度:最小割点集合中的顶点数。
割边(桥):删掉它之后,图必然会分裂为两个或两个以上的子图。
割边集合:如果有一个边集合,删除这个边集合以后,原图变成多个连通块,就称这个点集为割边集合。
边连通度:一个图的边连通度的定义为,最小割边集合中的边数。
缩点:把没有割边的连通子图缩为一个点,此时满足任意两点之间都有两条路径可达。
双连通分量:分为点双连通和边双连通。它的标准定义为:点连通度大于1的图称为点双连通图,边连通度大于1的图称为边双连通图。通俗地讲,满足任意两点之间,能通过两条或两条以上没有任何重复边的路到达的图称为双连通图。无向图G的极大双连通子图称为双连通分量。
求解方法
1.求强连通分量、割点、桥、缩点: 对于Tarjan算法中,我们得到了dfn和low两个数组, low[u]=min(low[u],dfn[v])——(u,v)为后向边,v不是u的子树; low[u]=min(low[u],low[v])——(u,v)为树枝边,v为u的子树; 下边对其进行讨论: 若low[v]>=dfn[u],则u为割点,u和它的子孙形成一个块。 因为这说明u的子孙不能够通过其他边到达u的祖先, 这样去掉u之后,图必然分裂为两个子图。 若low[v]>dfn[u],则(u,v)为割边。理由类似于上一种情况。 2.求双连通分量以及构造双连通分量: 对于点双连通分量,实际上在求割点的过程中就能顺便把每个点双连通分量求出。 建立一个栈,存储当前双连通分量,在搜索图时,每找到一条树枝边或后向边(非横叉边),就把这条边加入栈中。 如果遇到某时满足DFS(u)<=Low(v),说明u是一个割点,同时把边从栈顶一个个取出, 直到遇到了边(u,v),取出的这些边与其关联的点,组成一个点双连通分量。 割点可以属于多个点双连通分量,其余点和每条边只属于且属于一个点双连通分量。 对于边双连通分量,求法更为简单。只需在求出所有的桥以后,把桥边删除,原图变成了多个连通块,则每个连通块就是一个边双连通分量。 桥不属于任何一个边双连通分量,其余的边和每个顶点都属于且只属于一个边双连通分量。
Problem
hdu4378 Caocao's Bridges
Description
求权值最小的桥,特判如果最小桥值为0,则输出1
Code
1 |
|
hdu3394 Railway
Description
求桥的数量以及点双中 边数比点数多的边数之和
Code
1 |
|
hdu2460 Network
Description
给出一个无向图以及Q次询问,每次询问增加一条无向边,要求输出增加这条边后剩余的桥的数目
Solution
先求桥的数量,然后每次询问暴力跳LCA就能过
Code
1 |
|
hdu4587 TWO NODES
Description
n点的无向图,问删除两个点以后,该图最多被分成多少个联通快?
Solution
先枚举第一个点,然后跑一遍tarjan求出除去这个点之外的割点的数量,然后把去掉之后的联通块数量加那个值取max即可
Code
1 |
|
hdu4612 Warm up
Description
给一个图, 求增加一条边之后的桥的数量最少是多少。有重边
Solution
先求桥的数量然后减去缩点求直径的长度即可
Code
1 | //#pragma GCC optimize(2) |
hdu4694 Important Sisters
支配树模板
Code
1 | #include <bits/stdc++.h> |