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;
}
posted @ 2016-11-01 21:53  Krew  阅读(1561)  评论(0)    收藏  举报