1. 程式人生 > >【專題】Tarjan演算法介紹

【專題】Tarjan演算法介紹

一種由Robert Tarjan提出的求解有向圖強連通分量的線性時間的演算法。

Tarjan與無向圖連通性

·幾個定義

給定無向圖G=(V,E)
如果割掉點x,圖中的連通塊數量增加,則稱x為G的割點
如果割掉邊e,圖中的連通塊數量增加,則稱e為G的割邊

·時間戳

在圖的深度優先搜尋中,按照每個節點的訪問順序所給每個點編的號,該編號叫做“時間戳”,記為dfn[x]

·搜尋樹

在無向連通圖中任選一個節點出發進行深度優先搜尋,每個點只訪問一次。所有遞迴的邊構成的一棵樹稱為搜尋樹,所有形成環的邊稱為返祖邊

·追溯值

追溯值low[x]表示在x為根的子樹內,所有邊中能夠到達的點的最小的dfn(不包括父親節點)。
如果一條邊(x,y)是一條返祖邊,

low[x]=min(low[x],dfn[x]);
如果一條邊(x,y)是搜尋樹上的邊,low[x]=min(low[x],low[y]);

·橋

如果一條無向邊(x,y)是一條橋,一定滿足

dfn[x]<low[y]
證明:因為low[y]>dfn[x],所以在y節點的子樹內一定沒有一條邊可以到達x或比dfn[x]還要小的點。

·割點

如果一個點x是割點,一定滿足

dfn
[x]low[y]

證明:因為dfn[x]low[y],所以在以y點為根的子樹內一定沒有一條邊可以跳到x以上,所以當x割掉,子樹將獨立

無向圖與雙聯通分量

若一張無向聯通圖不存在割點,則稱它為點雙連通圖,若一張無向聯通圖不存在橋,則稱它為邊雙連通圖
無向圖中極大的點雙連通子圖叫點雙連通分量,極大的邊雙連通子圖叫邊雙連通分量,統稱為雙連通分量

邊雙連通分量(e-DCC)的求法

把無向圖中的所有橋都刪去,得到的就是若干個邊雙。

邊雙縮點

在某些時候,我們需要把邊雙縮成一個點使得原本的連通圖變成一個我們可以容易做的樹,這種操作就是把一個大的邊雙連通分量用一個點代替。
首先我們找到

low[x]=dfn[x]的點,這必定是一個邊雙的根。
證明:對於一個邊雙,我們知道在這個邊雙內沒有一條橋。既然滿足low[x]=dfn[x],則在x的子樹內沒有一個點有連邊到該點的上面,所以仍在棧中的點一定是以x為根的邊雙。
我們可以用一個棧來儲存我們經過的點,一旦這個點成為了雙連通分量中的點,就可以將其彈棧。

Code:
void tarjan(int x,int fa)
{
    dfn[x]=low[x]=++idx,st[++st[0]]=x;
    for (int i=last[x];i;i=next[i])
        if (tov[i]!=fa)
            if (!dfn[tov[i]])
                tarjan(tov[i],x),low[x]=min(low[x],low[tov[i]]);
            else
                low[x]=min(low[x],dfn[tov[i]]);
    if (low[x]==dfn[x])
    {
        ++tot;
        do
            dcc[st[st[0]]]=tot;
        while (st[st[0]--]!=x);
    }
}

點雙連通分量(v-DCC)的求法

對於點雙連通分量,需要在Tarjan裡面維護一個棧,每次將當前搜尋到的點加入棧中,當你發現x點滿足割點條件的時候,那麼仍在棧裡的點就是一個以x為根的點雙,把他們全部彈掉(注意:割點不要彈掉,因為一個割點有可能存在於在多個點雙中)

點雙的縮點

由於一個割點有可能存在於多個點雙之中,所有點雙的縮點不能像邊雙一樣直接用橋邊相連,我們需要新建節點來代表某個割點,用它把所有這個割點所在的點雙連線起來。
對於一幅圖
這裡寫圖片描述
它擁有的點雙就有
這裡寫圖片描述
那麼縮完點就是
這裡寫圖片描述

Code:

void tarjan(int x,int fa)
{
    dfn[x]=low[x]=++idx;
    for (int i=last[x];i;i=next[i])
        if (tov[i]!=fa)
            if (!dfn[tov[i]])
            {
                st[++top]=i,tarjan(tov[i],x);
                low[x]=min(low[x],low[tov[i]]);
                if (low[tov[i]]>=dfn[x])
                {
                    cut[x]=true;
                    ++fct[x],dcc[tot][++dcc[tot][0]]=x;
                    do
                        dcc[tot][++dcc[tot][0]]=st[top];
                    while (st[top--]!=i);
                }
            }
            else low[x]=min(low[x],dfn[tov[i]]);
}
cnt=tot;
for (i=1;i<=n;++i) if(cut[i]) new_id[i]=++tot;
for (i=1;i<=cnt;++i)
    for (j=0;j<=dcc[i][0];++j)
    {
        int x=dcc[i][j];
        if(cut[x])
        {
            insert(i,new_id[x]);
            insert(new_id[x],i);
        }else c[x]=i;//除割點外,其他點僅屬於1個v_DCC
    }

相關推薦

專題Tarjan演算法介紹

一種由Robert Tarjan提出的求解有向圖強連通分量的線性時間的演算法。 Tarjan與無向圖連通性 ·幾個定義 給定無向圖G=(V,E)G=(V,E) 如果割掉點x,圖中的連通塊數量增加,則稱x為G的割點 如果割掉邊e,圖中的連

18.12.30 sssxtarjan演算法

資料結構  dfn[i] :編號為i的結點在dfs遍歷圖的過程中的訪問序號(開始時間)  low[i] :從i結點出發dfs過程中i下方的結點能到達的最早的當前搜尋路徑上的結點的開始時間。(初始時 low[i]=dfn[i] ) 操作

演算法與資料結構專場BitMap演算法介紹

我們先來看個簡單的問題。假如給你20億個非負數的int型整數,然後再給你一個非負數的int型整數 t ,讓你判斷t是否存在於這20億數中,你會怎麼做呢?有人可能會用一個int陣列,然後把20億個數給存進去,然後再迴圈遍歷一下就可以了。想一下,這樣的話,時間複雜度是O(n),所需要的記憶體空間4byte *

專題歐幾里得演算法、擴充套件歐幾里得、乘法逆元

1.歐幾里得 用途 最大公因數和最小公倍數 定理:  gcd(a,b)=gcd(b,a%b)   證明: 我們令c=gcd(a,b) 令a=n∗c , b=m∗c a%b=a−k

LCATarjan離線演算法(並查集+dfs)模板

vector <int> Q[N]; int Find(int x) { if(x != fa[x]) return fa[x] = Find(fa[x]); return x; } void Union(int x, int y

轉載WEBRTC基本介紹

webrtc 數據流 應用 帶寬 工作 ogl 回聲 real 明顯 “WebRTC,名稱源自網頁實時通信(Web Real-Time Communication)的縮寫,是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,是谷歌2010年以6820萬美元收購

openstack項目day23:KVM介紹

進制 sed 與他 運行 之前 entos strong img 類型 閱讀目錄 什麽是kvm 為何要用kvm kvm的功能 常見虛擬化模式 KVM架構 KVM工具集合 一 什麽是kvm KVM 全稱 Kernel-Based Virtual Machine。也就是說

原創tarjan算法初步(強連通子圖縮點)

fin namespace 但是 申請 div 處理 sin point 沒有 【原創】tarjan算法初步(強連通子圖縮點) tarjan算法的思路不是一般的繞!!(不過既然是求強連通子圖這樣的回路也就可以稍微原諒了。。) 但是研究tarjan之前總得知道強連通分量是

1 地圖單位介紹

長度 分辨率 世界 地球 對角線 意義 常用 長度單位 計算機 1.常用單位 1)長度單位 1km(公裏)=1000m(米,公尺) 1m(米)=1000mm(毫米),1m=100cm(厘米) 1m=10dm(分米) 1m=3尺, 2)面積單位 1公頃=15畝,1公頃=

RAID技術介紹和總結

允許 pos distrib 數據讀取 body web服務器 data- 也有 丟失 轉自http://blog.jobbole.com/83808/ 簡介 RAID是一個我們經常能見到的名詞。但卻因為很少能在實際環境中體驗,所以很難對其原理 能有很清楚的認識和掌握。本文

專題數位DP

aid dfs .com 合並 all 習慣 else net 普通 【資料】 ★記憶化搜索:數位dp總結 之 從入門到模板 by wust_wenhao 論文:淺談數位類統計問題 數位計數問題解法研究 【記憶化搜索】 數位:數字從低位到高位依次為0~len-1。 高位限制

C# list介紹和用法

php 檢索 排序 c# reac ont 面向對象 類型 大型 一、LIST概述 所屬命名空間:System.Collections.Generic public class List<T> : IList<T>, ICollection

模板Tarjan縮點

pri set n) ans class namespace val names -a 洛谷3387 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4

專題計數問題(排列組合,容斥原理,卡特蘭數)

spl 狀態 ans 補集 方便 常用 括號 inf 不存在 ---下面都是學習的筆記,還沒有整理,比較淩亂,有需自取吧。--- 【排列組合】 <加法原理>做一件事情有n個方法,第i個方法有pi種方案,則一共有p1+p2+...+pn種方案。 <乘法原理&

html01_html的介紹

min 標記 gem 瀏覽器 -i bin 組織 難了 markup 【HTML專修介紹】 定義: HTML(HypertextMarkup Language),超文本標記語言 如何理解: (意思就是超越了文本,還能兼容圖片,視頻,聲音字節) 它的主要用處是什麽? 就是用來

專題區間dp

splay eve 回文 microsoft 傳送門 net sed 鏈接 bdc 1.【nyoj737】石子合並 傳送門:點擊打開鏈接 描述 有N堆石子排成一排,每堆石子有一定的數量。現要將N堆石子並成為一堆。合並的過程只能每次將相鄰的兩堆石子堆成一堆,每次合並

專題Spring

num spring 最全 https acl enables .com nbsp 最全的 Spring Boot【快速入門】 https://www.cnblogs.com/wmyskxz/p/9010832.html Spring常用註解 https://www.c

函式和常用模組day04:函式介紹(一)

本節內容 1、函式介紹 2、函式定義 3、為什麼要使用函式 一、介紹   在我們以往的學習程式設計的過程當中,碰到的最多的兩張程式設計方式或者說程式設計方法:面向過程和麵向物件。其實不管是哪一種,其實都是程式設計的方法論而已。但是現在有一種更古老的程式設計方式:函數語言程式設計,以它的不儲存的狀態,

筆記DLX演算法及常見應用

參考資料 精確覆蓋問題講解——grenet 數獨模型轉換——bl0ss0m DLX演算法求解數獨——grenet 問題引入 精確覆蓋問題: 有r個由1~n組成的集合S1,S2,S3....Sr,要求選擇若干集合,使得1~n恰好只在一個集合裡出現。 數獨問題: 在9×9的矩陣裡填數,使得每一行每

內功基礎演算法——字串

[1] Manacher  求一個字串中的最長迴文子串。 講解直接放ppt,複習能回憶起來就行。         1 #include <iostream> 2 #include <