tarjan算法求聯通塊中求割點和割邊

來自hiho的第五十二週,參考鏈接:http://hihocoder.com/contest/hiho52/problem/1


//tarjan中可見dfs_pos,low數組不需要初始化
//如果有多個聯通分塊,那麼就要枚舉每個未訪問過的點進行tarjan,進行tarjan前先將fa[i] = -1
//這裏的se爲set,存放割點;edge爲vector<pair<int,int> >,存放割邊
void tarjan(int u)
{	
	int num_son = 0;//以當前點爲樹根的子樹的個數
	vis[u] = 1;
	dfs_pos[u] = low[u] = ++jishu;//dfs_pos爲dfs序,low[u]是dfs序最小的祖先(沒有則爲自己)
	for(int i = head[u];~i;i = e[i].nex)
	{
		int v = e[i].v;
		if(!vis[v])
		{
			num_son++;
			fa[v] = u;//fa是父親
			tarjan(v);
			low[u] = min(low[u],low[v]);//遞歸求dfs序最小的的祖先
			if(fa[u] == -1 && num_son > 1)//若當前節點沒有父親且有兩個或兩個以上子樹,則這個點必爲割點
				se.insert(u);
			if(fa[u] != -1 && low[v] >= dfs_pos[u])//若當前點存在父親,且他的兒子中沒有回邊連到u或者u的祖先中,此點爲割點
				se.insert(u);
			if(low[v] > dfs_pos[u])//他的兒子沒有回邊連到u的祖先中
				edge.push_back(pii(min(u,v),max(u,v)));
		}
		else if(v != fa[u])//如果拜訪到已經被訪問的點
			low[u] = min(low[u],low[v]);
	}
}


發佈了50 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章