题意:给出一个n个点m条边的无向图,求其割点。
思路:tarjan求割点模板题。
tarjan(求割点):遍历整个图,则整个图可转化为一棵树(附带着有回边)。设置两个数组,dfn[i](记录搜索到i的时间),low[i](记录在i的子树中通过非父子边能够遍历到的最早的dfn)。
那么如何判断一个点是否是割点?一个点v有两种情况。
- v为树根,则当v有不止一棵子树时,v为割点。
- v非根节点,则当v的子树中没有边指向v的祖先时v为割点。(即v的孩子中存在i使得low[i]>=dfn[v])
现在已经知道怎么判断一个点是否为割点了,那如何求low?可以分为两种情况。
- 当edge(v,i)为树边时,low[v]=min(low[v],low[i])
- 当edge(v,i)为回边时,low[v]=min(low[v],dfn[i])
如果是求割边呢?
edge(v,i)当且仅当low[i]>dfn[v]时,为割边。
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
#define NUM 110000
#define INF 0x3f3f3f3f
const int p &