DFS and Similar
DFS and Similar
[ 1 ] DFS 's Basement
时间戳:记录每个节点入栈和出栈时间
DFS树:遍历整个图后,所有节点加上遍历过的边所构成的树
树边:DFS树中原图的边
反向边:DFS树中将一个节点连接至它祖先节点的祖先的边
void DFS(int k)
{
pre[k]=++Fate_clock;
rep(i,0,sz(G[k])-1)
if (!pre[G[k][i]]) DFS(G[k][i]);
pos[k]=++Fate_clock;
}
[2] Cut Vertex and Bridge
割点:若将一个图中的某个点及它的所有边删除后使整个图不联通,则它是这个图的一个割点
桥边:若将一个图中的某条边删除后,整个图不联通,则它是这个图的一条桥边
对于求出割点的问题,我们要先求出DFS树,令\(low(u)\)为结点\(u\)及其子结点所能连回的祖先结点最小pre值,则:
一个结点是此图的割点,当且仅当它存在一个子结点\(v\),使得\(low(v) \geq pre(u)\)
一条边是此图的桥边,当且仅当点\(u\)存在一个子结点\(v\),使得\(low(v)>pre(u)\)
void DFS(int k,int fa) //Cut Vertex
{
int child=0;
pre[k]=++Fate_clock,low[k]=pre[k];
rep(i,0,sz(G[k])-1)
{
if (!pre[G[k][i]])
{
child++;
DFS(G[k][i],k);
low[k]=min(low[k],low[G[k][i]]);
if (low[G[k][i]]>=pre[k]) iscut[k]=1;
}
else
if (G[k][i]!=fa) low[k]=min(low[k],pre[G[k][i]]);
}
if ((fa<0)&&(child==1)) iscut[k]=0; //注意特判根节点
pos[k]=++Fate_clock;
}
void DFS(int k,int fa) //Bridge
{
int child=0;
pre[k]=++Fate_clock,low[k]=pre[k];
rep(i,0,sz(G[k])-1)
{
if (!pre[G[k][i]])
{
child++;
DFS(G[k][i],k);
low[k]=min(low[k],low[G[k][i]]);
if (low[G[k][i]]>pre[k]) size++,bx[size]=k,by[size]=G[k][i];
}
else
if (G[k][i]!=fa) low[k]=min(low[k],pre[G[k][i]]);
}
pos[k]=++Fate_clock;
}

浙公网安备 33010602011771号