hiho圖的聯通性(自留)

無向圖割邊割點算法

而當(u,v)為樹邊且low[v]>dfn[u]時,表示v節點只能通過該邊(u,v)與u連通,那么(u,v)即為割邊。

 1 void dfs(int u) {
 2     //記錄dfs遍歷次序
 3     static int counter = 0;    
 4     
 5     //記錄節點u的子樹數
 6     int children = 0;
 7     
 8     ArcNode *p = graph[u].firstArc;
 9     visit[u] = 1;
10 
11     //初始化dfn與low
12     dfn[u] = low[u] = ++counter;
13 
14     for(; p != NULL; p = p->next) {
15         int v = p->adjvex;
16         
17         //節點v未被訪問,則(u,v)為樹邊
18         if(!visit[v]) {
19             children++;
20             parent[v] = u;
21             dfs(v);
22 
23             low[u] = min(low[u], low[v]);
24 
25             //case (1)
26             if(parent[u] == NIL && children > 1) {
27                 printf("articulation point: %d\n", u);
28             }
29 
30             //case (2)
31             if(parent[u] != NIL && low[v] >= dfn[u]) {
32                 printf("articulation point: %d\n", u);
33             }
34             
35             //bridge
36             if(low[v] > dfn[u]) {
37                 printf("bridge: %d %d\n", u, v);
38             }
39         }
40 
41         //節點v已訪問,則(u,v)為回邊
42         else if(v != parent[u]) {
43             low[u] = min(low[u], dfn[v]);
44         }
45     }
46 }
View Code

?

邊雙聯通分量算法

對于一個無向圖的子圖,當刪除其中任意一個點后,不改變圖內點的連通性,這樣的子圖叫做點的雙連通子圖。而當子圖的邊數達到最大時,叫做點的雙連通分量。

直觀的做法自然先用上周的算法求出所有橋,去掉所有橋之后再做DFS求出每一個連通子圖。我們這周要介紹一種更"抽象"的算法,通過在Tarjan算法當中巧妙地用一個棧來統計出每一個組內的節點,其代碼如下:

 1 void dfs(int u) {
 2     //記錄dfs遍歷次序
 3     static int counter = 0;    
 4     
 5     //記錄節點u的子樹數
 6     int children = 0;
 7     
 8     ArcNode *p = graph[u].firstArc;
 9     visit[u] = 1;
10 
11     //初始化dfn與low
12     dfn[u] = low[u] = ++counter;
13     
14     //將u加入棧
15     stack[++top] = u;
16 
17     for(; p != NULL; p = p->next) {
18         int v = p->adjvex;
19         
20         //節點v未被訪問,則(u,v)為樹邊
21         if(!visit[v]) {
22             children++;
23             parent[v] = u;
24             dfs(v);
25 
26             low[u] = min(low[u], low[v]);
27             if (low[v] > dfn[u]) {
28                 printf("bridge: %d %d\n", u, v);    // 該邊是橋
29                 bridgeCnt++;  
30             }
31         }
32 
33         //節點v已訪問,則(u,v)為回邊
34         else if(v != parent[u]) {
35             low[u] = min(low[u], dfn[v]);
36         }
37     }
38     
39     if (low[u] == dfn[u])
40     {
41         // 因為low[u] == dfn[u],對(parent[u],u)來說有dfn[u] > dfn[ parent[u] ],因此low[u] > dfn[ parent[u] ]
42         // 所以(parent[u],u)一定是一個橋,那么此時棧內在u之前入棧的點和u被該橋分割開
43         // 則u和之后入棧的節點屬于同一個組
44         將從u到棧頂所有的元素標記為一個組,并彈出這些元素。
45     }
46 }
View Code

?

強連通分量

對于有向圖上的2個點a,b,若存在一條從a到b的路徑,也存在一條從b到a的路徑,那么稱a,b是強連通的。
對于有向圖上的一個子圖,若子圖內任意點對(a,b)都滿足強連通,則稱該子圖為強連通子圖。
非強連通圖有向圖的極大強連通子圖,稱為強連通分量。
特別地,和任何一個點都不強連通的單個點也是一個強連通分量。

 1 tarjan(u)
 2 {
 3     Dfn[u]=Low[u]=++Index                      // 為節點u設定次序編號和Low初值
 4     Stack.push(u)                              // 將節點u壓入棧中
 5     for each (u, v) in E                       // 枚舉每一條邊
 6         if (v is not visted)                   // 如果節點v未被訪問過
 7             tarjan(v)                          // 繼續向下找
 8             Low[u] = min(Low[u], Low[v])
 9         else if (v in Stack)                   // 如果節點v還在棧內(很重要,無向圖沒有這一步)
10             Low[u] = min(Low[u], Dfn[v])
11     if (Dfn[u] == Low[u])                      // 如果節點u是強連通分量的根
12         repeat
13             v = Stack.pop                      // 將v退棧,為該強連通分量中一個頂點
14             mark v                             // 標記v,同樣通過棧來找連通分量
15         until (u == v)
16 }
View Code


scc + 縮點 + topo

?

對于一個無向圖的子圖,當刪除其中任意一個點后,不改變圖內點的連通性,這樣的子圖叫做點的雙連通子圖。而當子圖的邊數達到最大時,叫做點的雙連通分量。

???????????????????????????????????????

對于橋的兩種情況,它分割個區域數剛好就等于割點數+1;而連通分量內的割點同樣也是,每存在一個割點,點的雙連通分量就增加一個。

點的雙連通分量就等于割點數量加1。

每存在一個割點,就把一個區域一分為二,所以最后的結果也就是統計割點的數量就可以了。而對于分組具體情況,我們仍然采用棧來輔助我們記錄

 1 void dfs(int u) {
 2     //記錄dfs遍歷次序
 3     static int counter = 0;    
 4     
 5     //記錄節點u的子樹數
 6     int children = 0;
 7     
 8     ArcNode *p = graph[u].firstArc;
 9     visit[u] = 1;
10 
11     //初始化dfn與low
12     dfn[u] = low[u] = ++counter;
13 
14     for(; p != NULL; p = p->next) {
15         int v = p->adjvex;
16         if(edge(u,v)已經被標記) continue; 
17 
18         //節點v未被訪問,則(u,v)為樹邊
19         if(!visit[v]) {
20             children++;
21             parent[v] = u;
22             edgeStack[top++] = edge(u,v); // 將邊入棧
23             dfs(v);
24             
25             low[u] = min(low[u], low[v]);
26 
27             //case (1)
28             if(parent[u] == NIL && children > 1) {
29                 printf("articulation point: %d\n", u);
30                 // mark edge
31                 // 將邊出棧,直到當前邊出棧為止,這些邊標記為同一個組
32                 do {
33                     nowEdge = edgeStack[top];
34                     top--;
35                     // 標記nowEdge
36                 }    while (nowEdge != edge(u,v))
37             }
38 
39             //case (2)
40             if(parent[u] != NIL && low[v] >= dfn[u]) {
41                 printf("articulation point: %d\n", u);
42                 // mark edge
43                 // 將邊出棧,直到當前邊出棧為止,這些邊標記為同一個組
44                 do {
45                     nowEdge = edgeStack[top];
46                     top--;
47                     // 標記nowEdge
48                 }    while (nowEdge != edge(u,v))
49             }
50             
51         }
52 
53         //節點v已訪問,則(u,v)為回邊
54         else if(v != parent[u]) {
55             edgeStack[top++] = edge(u,v);
56             low[u] = min(low[u], dfn[v]);
57         }
58     }
59 }
View Code

?

轉載于:https://www.cnblogs.com/usedrosee/p/4693121.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/397733.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/397733.shtml
英文地址,請注明出處:http://en.pswp.cn/news/397733.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《Git權威指南》筆記2

2019獨角獸企業重金招聘Python工程師標準>>> ###Git克隆 Git使用git clone命令實現版本庫克隆&#xff0c;主要有如下3種用法&#xff1a; 1&#xff09;git clone <repository> <direcctory> 將repository指向的版本庫創建一個克隆島directory目錄。目…

SQL數據庫掛起 SQL數據庫附加報錯 SQL數據庫824錯誤修復

SQL數據庫掛起 SQL數據庫附加報錯 SQL數據庫824錯誤修復 數據類型 MSSQL 2012數據大小 4.5 GB故障檢測 附加數據庫提示824錯誤 一般是由于斷電非法關機導致頁面損壞。客戶要求 恢復數據庫數據 ERP可直接使用。修復結果 文件傳來后 檢測發現頁面沒有及時正常關閉導致SQL認為頁不…

查找算法

a. 線性查找&#xff1a;從數據中&#xff0c;第一個元素開始查找&#xff0c;將其與查找的值進行比對&#xff0c;如果相同&#xff0c;就停止查找&#xff0c;如果不相同&#xff0c;則繼續下一個元素的比對。直到查找到匹配的值&#xff0c;或者是有數據遍歷完畢&#xff0c…

mysql測試數據圖表_mysql測試數據表

1.截取至后盾人用于mysql數據測試請在navicat中執行一下命令生成測試數據表/*Navicat Premium Data TransferSource Server : 我的本地連接Source Server Type : MySQLSource Server Version : 50726Source Host : localhost:3306Source Schema : laravelTarget Server Type : …

常用歸檔壓縮命令

1. 打包tar打包表示把一堆文件變成一個tar ####打包工具-f ####指定生成包的名字-c ####創建包-v ####顯示創建過程-t ####查看包中內容-x ####解包-r ####添加文件到包中--delete filename ##刪除包中指定文件--get filename ##取出包中指定文件cffrcvf 等組合使用2. 壓縮…

spring集合的注入

<bean id"date" class"java.util.Date"></bean> <bean id"test" class"test.Test"> <!--注入list-->   <property name"list">     <list>       <value>1</valu…

爬蟲實戰篇---12306搶票爬蟲

&#xff08;1&#xff09;、前言 &#xff08;此代碼經過我的實測具有較強的實用型)每逢佳節&#xff0c;大家對于回家搶票這件事是不是特別頭疼呢&#xff1f;今天我在網上發現了這個代碼&#xff0c;通過一天的學習&#xff0c;與大家分析下&#xff0c;大家可以直接拿來進行…

php和mysql處理樹狀_分級_無限分類_分層數據的方法_PHP和MySQL處理樹狀、分級、無限分類、分層數據的方法...

文章標題中的多個詞語表達的其實是一個意思&#xff0c;就是遞歸分類數據&#xff0c;分級數據非常類似數據結構中的樹狀結構&#xff0c;即每個節點有自己的孩子節點&#xff0c;孩子結點本身也是父親節點。這是一個遞歸、分層形式。可以稱之為樹形層級數據。層級數據結構是編…

LeetCode 70. Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 一開始想用排列組合的方式&#xff0c;但是公式不太好些&#xff0c;后來想用遞歸的方式&#x…

04 java 基礎:數據類型

java 數據類型&#xff1a;基本類型與引用類型 基本類型&#xff1a;數值型&#xff0c;其中數值型分為整型、浮點型&#xff0c;整型包括 byte、short 、int、long &#xff0c;默認為 int 類型。浮點類型分為單精度、雙精度&#xff0c;分為 float、double &#xff0c;默認為…

Git 遠程倉庫分支管理

目錄 目錄速查表關聯遠程代碼倉庫克隆遠程倉庫 分支管理創建分支 切換分支合并分支刪除分支解決沖突速查表 指令作用git branch查看分支git branch newBranchName創建分支git checkout branchName切換分支giit checkout -b newBranchName創建切換分支git merge branchName合并分…

call,apply

1.call要逐個傳入參數 2apply方法的必須 function curry(fn){var argsArray.prototype.slice.call(arguments,1);return function(){var innerArgsArray.prototype.slice.call(arguments);var finalArgsargs.concat(innerArgs);console.log(finalArgs);return fn(finalArgs);//…

2018美團CodeM編程大賽 Round A Problem 2 下棋 【貪心】

應該一眼看出來是貪心題&#xff0c;然后想最優解是什么。正確的貪心策略是【原棋盤上每個位置的棋子】都往最近的左邊【目標棋盤上棋子】移動&#xff0c;如果左邊沒有棋子了那就閑置最后處理&#xff0c;如果目標棋盤在該位置上也有棋子&#xff0c;那就算距離為0&#xff08…

idea清理svn信息_IntelliJ IDEA SVN的賬號修改 信息清除

來到編譯器的setting設置 搜索subversion 點擊subversion 找到下面的clear auth...按鈕,點擊一下 就可以了…如果我們不小心輸入svn賬號錯誤的話,后面就一直提示認證失敗,不能checkout代碼. 這個是因為svn把你輸入的賬號進行了緩存. 如果我們想重新輸入新的賬號,必須要清除緩存…

同步手繪板——json

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基于ECMAScript的一個子集。 JSON采用完全獨立于語言的文本格式&#xff0c;但是也使用了類似于C語言家族的習慣&#xff08;包括C、C、C#、Java、JavaScript、Perl、Python等&#xff09;。這些特性使JSON成為…

[HNOI2008]玩具裝箱TOY

洛谷題目連接:[HNOI2008]玩具裝箱TOY 題目描述 P教授要去看奧運&#xff0c;但是他舍不下他的玩具&#xff0c;于是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮&#xff0c;其可以將任意物品變成一堆&#xff0c;再放到一種特殊的一維容器中。P教授有編號為1...N的…

C語言-結構體內存對齊

C語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎&#xff0c;但一不小心就會弄錯。寫出一個struct&#xff0c;然后sizeof&#xff0c;你會不會經常對結果感到奇怪&#xff1f;sizeof的結果往往都比你聲明的變量總長度要大&#xff0c;這是怎么回…

nginx 二進制包安裝mysql_二進制安裝mysql5.7

下載地址&#xff1a;https://downloads.mysql.com/archives/community/[rootlocalhost soft]# lsmysql-5.7.17-linux-glibc2.5-x86_64.tar.gz nginx-1.12.2 nginx-1.12.2.tar.gz[rootlocalhost soft]#1.詳細描安裝的過程1.1關閉防火墻systemctl stop firewalld.service #停止f…

.NET 類型(Types)的那些事

引言 您是.Net工程師&#xff1f;那 .NetFramework中的類型您知道有三大類嗎&#xff1f;&#xff08;除了引用類型和值類型&#xff0c;還有&#xff1f;&#xff09; 引用類型一定在“堆”上&#xff0c;值類型一定在“棧”上&#xff1f; 那引用類型在內存中的布局細節您又知…

幾種去除數組中重復元素的方法、數組去重

工作中遇到的一個問題&#xff0c;就是去除數組中重復的元素&#xff0c;記錄一下幾種有效的方法&#xff1a; 第一種思路&#xff1a;遍歷要刪除的數組arr, 把元素分別放入另一個數組tmp中&#xff0c;在判斷該元素在arr中不存在才允許放入tmp中。 <!DOCTYPE html> <…