圖論基礎(chǔ)

一钓猬、圖的初識(shí)

在一個(gè)社交網(wǎng)絡(luò)中普舆,每個(gè)帳號(hào)和他們之間的關(guān)系構(gòu)成了一張巨大的網(wǎng)絡(luò),就像下面這張圖:

image.png

那么在電腦中表悬,我們要用什么樣的數(shù)據(jù)結(jié)構(gòu)來(lái)保存這個(gè)網(wǎng)絡(luò)呢弥锄?這個(gè)網(wǎng)絡(luò)需要用一個(gè)之前課程里未提到過(guò)的數(shù)據(jù)結(jié)構(gòu),也就是接下來(lái)要講解的 結(jié)構(gòu)來(lái)保存蟆沫。

到底什么是圖籽暇?圖是由一系列頂點(diǎn)和若干連結(jié)頂點(diǎn)集合內(nèi)兩個(gè)頂點(diǎn)的邊組成的數(shù)據(jù)結(jié)構(gòu)。數(shù)學(xué)意義上的圖饥追,指的是由一系列點(diǎn)與邊構(gòu)成的集合图仓,這里我們只考慮有限集。通常我們用 G = (V, E) 表示一個(gè)圖結(jié)構(gòu)但绕,其中 V 表示點(diǎn)集救崔,E 表示邊集。

在頂點(diǎn)集合所包含的若干個(gè)頂點(diǎn)之間捏顺,可能存在著某種兩兩關(guān)系——如果某兩個(gè)點(diǎn)之間的確存在這樣的關(guān)系的話(huà)六孵,我們就在這兩個(gè)點(diǎn)之間連邊,這樣就得到了邊集的一個(gè)成員幅骄,也就是一條邊劫窒。對(duì)應(yīng)到社交網(wǎng)絡(luò)中,頂點(diǎn)就是網(wǎng)絡(luò)中的用戶(hù)拆座,邊就是用戶(hù)之間的好友關(guān)系主巍。

如果用邊來(lái)表示好友關(guān)系的話(huà),對(duì)于微信這種雙向關(guān)注的社交網(wǎng)絡(luò)沒(méi)有問(wèn)題挪凑,但是對(duì)于微博這種單向關(guān)注的要如何表示呢孕索?

于是引出了兩個(gè)新的概念:有向邊無(wú)向邊

1.1 有向邊無(wú)向邊躏碳。

簡(jiǎn)而言之搞旭,一條有向邊必然是從一個(gè)點(diǎn)指向另一個(gè)點(diǎn),而相反方向的邊在有向圖中則不一定存在菇绵;而有的時(shí)候我們并不在意構(gòu)成一條邊的兩個(gè)頂點(diǎn)具體誰(shuí)先誰(shuí)后肄渗,這樣得到的一條邊就是無(wú)向邊。就像在微信中咬最,AB 的好友翎嫡,那 B 也一定是 A 的好友,而在微博中永乌,A 關(guān)注 B 并不意味著 B 也一定關(guān)注 A钝的。

對(duì)于圖而言翁垂,如果圖中所有邊都是無(wú)向邊,則稱(chēng)為無(wú)向圖硝桩,反之稱(chēng)為有向圖。

簡(jiǎn)而言之枚荣,無(wú)向圖中的邊是“好友”碗脊,而有向圖中的邊是“關(guān)注”。一般而言橄妆,我們?cè)跀?shù)據(jù)結(jié)構(gòu)中所討論的圖都是有向圖衙伶,因?yàn)橛邢驁D相比無(wú)向圖更具有代表性。實(shí)際上害碾,無(wú)向圖可以由有向圖來(lái)表示矢劲。如果 AB 兩個(gè)點(diǎn)之間存在無(wú)向邊的話(huà),那用有向圖也可以表示為 AB 兩點(diǎn)之間同時(shí)存在 ABBA 兩條有向邊慌随。仍然以社交網(wǎng)絡(luò)舉例:雖然微博中并不存在明確定義的好友關(guān)系芬沉,但是一般情況下,如果你和另一個(gè) ID 互相關(guān)注的話(huà)阁猜,那么我們也可以近似認(rèn)為丸逸,你和 TA 是好友。

1.2 圖的準(zhǔn)確定義

我們來(lái)形式化地定義一下圖:圖是由頂點(diǎn)集合(簡(jiǎn)稱(chēng) 點(diǎn)集)和頂點(diǎn)間的邊(簡(jiǎn)稱(chēng) 邊集)組成的數(shù)據(jù)結(jié)構(gòu)剃袍,通常用 G(V, E) 來(lái)表示黄刚。其中點(diǎn)集用 V(G) 來(lái)表示,邊集用 E(G) 來(lái)表示民效。在 無(wú)向圖 中憔维,邊連接的兩個(gè)頂點(diǎn)是無(wú)序的,這些邊被稱(chēng)為 無(wú)向邊畏邢。例如下面這個(gè)無(wú)向圖 G业扒,其點(diǎn)集 V(G)=\{1,2,3,5,6\},邊集為 E(G)=\{(1,2),(2,3),(1,5),(2,6),(5,6)\}棵红。

image.png

而在有向圖中凶赁,邊連接的兩個(gè)頂點(diǎn)之間是有序的。箭頭的方向就表示有向邊的方向逆甜。例如下面這張有向圖 G'

image.png

其點(diǎn)集 V(G')=\{1,2,3,5,6\}虱肄,邊集為 E(G')=\{(1,2),(2,3),(2,6),(6,5),(1,5)\}。對(duì)于每條邊 (u,v)交煞,我們稱(chēng)其為從 uv 的一條有向邊咏窿,u 是這條有向邊的 起點(diǎn)v 是這條有向邊的 終點(diǎn)素征。注意在有向圖中集嵌,(u,v)(v,u) 是不同的兩條有向邊萝挤。

二、圖的特征

2.1 圖的分類(lèi)

有很少邊或桓贰(如 e < n\log n怜珍,e 指邊數(shù),n 指頂點(diǎn)數(shù))的圖稱(chēng)為 稀疏圖凤粗,反之稱(chēng)為 稠密圖酥泛。對(duì)應(yīng)到微博里,如果在一個(gè)圈內(nèi)嫌拣,同學(xué)們都互相關(guān)注柔袁,則我們可以認(rèn)為該關(guān)系圖是一個(gè)稠密圖,如果只有幾個(gè)人關(guān)注了別人异逐,則我們可以認(rèn)為這是一個(gè)稀疏圖捶索。如果圖中邊集為空,則稱(chēng)該圖為 零圖灰瞻。

如果無(wú)向圖中任何一對(duì)頂點(diǎn)之間都有一條邊相連腥例,也就是有 \frac{n \times (n - 1)}{2} 條不重復(fù)的邊,則這個(gè)無(wú)向圖被稱(chēng)為 完全圖箩祥。類(lèi)似地院崇,如果有向圖中任何一對(duì)頂點(diǎn) u,v 之間都有兩條有向邊 (u,v), (v, u) 相連,則稱(chēng)這個(gè)有向圖為 有向完全圖袍祖。下圖就是由 4 個(gè)頂點(diǎn)組成的無(wú)向完全圖底瓣。

image.png

對(duì)于一個(gè)圖,如果以任意一個(gè)點(diǎn)為起點(diǎn)蕉陋,在圖上沿著邊走都可以到達(dá)其他所有點(diǎn)(有向圖必須沿有向邊的方向)捐凭,那么這個(gè)圖就是連通圖。顯然完全圖一定是連通圖凳鬓。

2.2 度的概念

在無(wú)向圖中茁肠,頂點(diǎn)的 是指某個(gè)頂點(diǎn)連出的邊數(shù)。例如在下圖中缩举,頂點(diǎn) b 的度數(shù)為 3垦梆,頂點(diǎn) a 的度數(shù)為 4

image.png

在有向圖中仅孩,和度對(duì)應(yīng)的是 入度出度 這兩個(gè)概念托猩。頂點(diǎn)的入度是指以該頂點(diǎn)為終點(diǎn)的有向邊數(shù)量;頂點(diǎn)的出度是指以頂點(diǎn)為起點(diǎn)的有向邊數(shù)量辽慕。需要注意的是京腥,在有向圖里,頂點(diǎn)是沒(méi)有 的概念的溅蛉。例如在下圖中公浪,頂點(diǎn) a 的入度為 1他宛,出度為 3;頂點(diǎn) c 的入度為 2欠气,出度為 2厅各。

image.png

2.3 度的性質(zhì)

在無(wú)向圖或有向圖中,頂點(diǎn)的度數(shù)總和為邊數(shù)的兩倍晃琳,即:
|E|=\frac{1}{2}\sum_{i=1}^n deg(u_i)
而在有向圖中讯检,有一個(gè)很明顯的性質(zhì)就是,所有頂點(diǎn)的入度和等于出度和卫旱。

三、鄰接矩陣

這一節(jié)我們來(lái)學(xué)習(xí)的圖的一種儲(chǔ)存方式——鄰接矩陣围段。

3.1 鄰接矩陣與圖

什么是鄰接矩陣呢顾翼?所謂鄰接矩陣存儲(chǔ)結(jié)構(gòu)就每個(gè)頂點(diǎn)用一個(gè)一維數(shù)組存儲(chǔ)邊的信息,這樣所有點(diǎn)合起來(lái)就是用矩陣表示圖中各頂點(diǎn)之間的鄰接關(guān)系奈泪。所謂矩陣其實(shí)就是二維數(shù)組适贸。

對(duì)于有 n 個(gè)頂點(diǎn)的圖 G = (V, E) 來(lái)說(shuō),我們可以用一個(gè) n \times n 的矩陣 A 來(lái)表示 G 中各頂點(diǎn)的相鄰關(guān)系涝桅,如果 v_iv_j 之間存在邊(或话葑恕),則 A[i][j] = 1冯遂,否則 A[i][j] = 0蕊肥。下圖為有向圖 G_1 和無(wú)向圖 G_2 對(duì)應(yīng)的鄰接矩陣:

image.png

image.png

image.png

image.png

一個(gè)圖的鄰接矩陣是唯一的,矩陣的大小只與頂點(diǎn)個(gè)數(shù) N 有關(guān)蛤肌,是一個(gè) N \times N 的矩陣壁却。前面我們已經(jīng)介紹過(guò),在無(wú)向圖里裸准,如果頂點(diǎn) v_iv_j 之間有邊展东,則可認(rèn)為頂點(diǎn) v_iv_j 有邊,頂點(diǎn) v_jv_i 也有邊炒俱。對(duì)應(yīng)到鄰接矩陣?yán)镅嗡啵瑒t有 A[i][j] = A[j][i] = 1。因此我們可以發(fā)現(xiàn)权悟,無(wú)向圖的鄰接矩陣是一個(gè)對(duì)稱(chēng)矩陣砸王。

在鄰接矩陣上,我們可以直觀(guān)地看出兩個(gè)頂點(diǎn)之間是否有邊(或唤┣邸)处硬,并且很容易求出每個(gè)頂點(diǎn)的度,入度和出度拇派。

這里我們以 G_1 為例荷辕,演示下如何利用鄰接矩陣計(jì)算頂點(diǎn)的入度和出度凿跳。頂點(diǎn)的出度,即為鄰接矩陣上點(diǎn)對(duì)應(yīng)行上所有值的總和疮方,比如頂點(diǎn) 1 出度即為 0 + 1 + 1 + 1 = 3控嗜;而每個(gè)點(diǎn)的入度即為點(diǎn)對(duì)應(yīng)列上所有值的總和,比如頂點(diǎn) 3 對(duì)應(yīng)的入度即為 1 + 0 + 0 + 1 = 2骡显。

image.png
image.png

接下來(lái)我們就先一起學(xué)習(xí)構(gòu)造和使用鄰接矩陣的方法疆栏。鄰接矩陣是一個(gè)由 10 構(gòu)成的矩陣。處于第 i 行惫谤、第 j 列上的元素 10 分別代表頂點(diǎn) ij 之間存在或不存在一條有向邊壁顶。

顯然在構(gòu)造鄰接矩陣的時(shí)候,我們需要實(shí)現(xiàn)一個(gè)整型的二維數(shù)組溜歪。由于當(dāng)前的圖還是空的若专,因此我們還要把這個(gè)二維數(shù)組中的每個(gè)元素都初始化為 0

在構(gòu)造好了一個(gè)圖的結(jié)構(gòu)后蝴猪,我們需要把圖中各邊的情況對(duì)應(yīng)在鄰接矩陣上调衰。實(shí)際上,這一步的實(shí)現(xiàn)非常簡(jiǎn)單自阱,當(dāng)從頂點(diǎn) xy 上存在邊時(shí)嚎莉,我們只要把二維數(shù)組對(duì)應(yīng)的位置置為 1 就好了。

image.png

用鄰接矩陣來(lái)構(gòu)建圖需要如下幾步沛豌,我們可以用二維數(shù)組G來(lái)表示一個(gè)圖趋箩。

3.2 初始化

初始化的過(guò)程很簡(jiǎn)單,只需要把數(shù)組初始化為 0 即可琼懊「篝ぃ可以借助memset來(lái)快速地將一個(gè)數(shù)組中的所有元素都初始化為 0

memset(G, 0, sizeof(G));

注意哼丈,memset只能用來(lái)初始化 0-1启妹,并且需要加上頭文件cstring

上面的代碼等價(jià)于:

for (int i = 0; i < N1; i++) { // N1 為數(shù)組第一維大小
    for (int j = 0; j < N2; j++) { // N2 為數(shù)組第二維大小
        G[i][j] = 0;
    }
}

當(dāng)然我們平常使用鄰接矩陣的時(shí)候下標(biāo)只用 1n 或者 0n - 1 (這個(gè)看題目中點(diǎn)的編號(hào))醉旦。

3.3 鄰接矩陣元素的修改

插入邊

如果插入一條無(wú)向邊 (u,v)饶米,只需要

G[u][v] = 1;
G[v][u] = 1;

也可以寫(xiě)成G[u][v] = G[v][u] = 1;

如果插入一條有向邊 (u,v)车胡,只需要G[u][v] = 1;檬输。

訪(fǎng)問(wèn)邊

如果G[u][v] = 1,說(shuō)明有一條從 uv 的邊匈棘,否則沒(méi)有從 uv 的邊丧慈。

3.4 帶權(quán)值的圖

在前面的課程中,圖中的邊都只是用來(lái)表示兩個(gè)點(diǎn)之間是否存在關(guān)系,而沒(méi)有體現(xiàn)出兩個(gè)點(diǎn)之間關(guān)系的強(qiáng)弱逃默。比如在社交網(wǎng)絡(luò)中鹃愤,不能單純地用 0茎辐、1 來(lái)表示兩個(gè)人否為朋友浅缸。當(dāng)兩個(gè)人是朋友時(shí),有可能是很好的朋友怔接,也有可能是一般的朋友吟税,還有可能是不熟悉的朋友凹耙。

我們用一個(gè)數(shù)值來(lái)表示兩個(gè)人之間的朋友關(guān)系強(qiáng)弱,兩個(gè)人的朋友關(guān)系越強(qiáng)肠仪,對(duì)應(yīng)的值就越大肖抱。而這個(gè)值就是兩個(gè)人在圖中對(duì)應(yīng)的邊的權(quán)值,簡(jiǎn)稱(chēng) 邊權(quán)异旧。對(duì)應(yīng)的圖我們稱(chēng)之為 帶權(quán)圖虐沥。

如下就是一個(gè)帶權(quán)圖,我們把每條邊對(duì)應(yīng)的邊權(quán)標(biāo)記在邊上:

image.png

帶權(quán)圖也分成帶權(quán)有向圖和帶權(quán)無(wú)向圖泽艘。前面學(xué)到的關(guān)于圖的性質(zhì)在帶權(quán)圖上同樣成立。實(shí)際上镐依,我們前面學(xué)習(xí)的圖是一種特殊帶權(quán)圖匹涮,只不過(guò)圖中所有邊的權(quán)值只有 1 一種;而在帶權(quán)圖中槐壳,邊的權(quán)值可以是任意的然低。

用鄰接矩陣存儲(chǔ)帶權(quán)圖和之前的方法一樣,用G[a][b]來(lái)表示 ab 之間的邊權(quán)(我們需要用一個(gè)數(shù)值來(lái)表示邊不存在务唐,如0)雳攘。同樣,對(duì)于無(wú)向圖枫笛,這個(gè)矩陣依然是對(duì)稱(chēng)的吨灭。

image.png
image.png

如上所示,左邊的圖對(duì)應(yīng)的右邊的鄰接矩陣刑巧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喧兄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子啊楚,更是在濱河造成了極大的恐慌吠冤,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恭理,死亡現(xiàn)場(chǎng)離奇詭異拯辙,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)颜价,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)涯保,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)诉濒,“玉大人,你說(shuō)我怎么就攤上這事遭赂⊙撸” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵撇他,是天一觀(guān)的道長(zhǎng)茄猫。 經(jīng)常有香客問(wèn)我,道長(zhǎng)困肩,這世上最難降的妖魔是什么划纽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮锌畸,結(jié)果婚禮上勇劣,老公的妹妹穿的比我還像新娘。我一直安慰自己潭枣,他們只是感情好比默,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著盆犁,像睡著了一般命咐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谐岁,一...
    開(kāi)封第一講書(shū)人閱讀 51,610評(píng)論 1 305
  • 那天醋奠,我揣著相機(jī)與錄音,去河邊找鬼伊佃。 笑死窜司,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的航揉。 我是一名探鬼主播塞祈,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼迷捧!你這毒婦竟也來(lái)了织咧?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤漠秋,失蹤者是張志新(化名)和其女友劉穎笙蒙,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體庆锦,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捅位,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艇搀。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尿扯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出焰雕,到底是詐尸還是另有隱情衷笋,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布矩屁,位于F島的核電站辟宗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏吝秕。R本人自食惡果不足惜泊脐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烁峭。 院中可真熱鬧容客,春花似錦、人聲如沸约郁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鬓梅。三九已至调煎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間己肮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工悲关, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谎僻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓寓辱,卻偏偏與公主長(zhǎng)得像艘绍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秫筏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 圖論基礎(chǔ) 1诱鞠、圖的定義 圖(Graph)是由頂點(diǎn)的有窮非空集合和頂點(diǎn)之間邊的集合組成,通常表示為:G(V,E)这敬,其...
    jqboooo閱讀 294評(píng)論 0 0
  • 概念 圖是由頂點(diǎn)V和邊E的集合組成的二元組航夺,記G=(V,E) 有向圖、無(wú)向圖崔涂、有權(quán)圖阳掐、無(wú)權(quán)圖、連通圖(聯(lián)通分量)、...
    歐文坐公交閱讀 739評(píng)論 0 0
  • 圖論基礎(chǔ)(Graph Theory) 圖是由結(jié)點(diǎn)(Vertex)和邊(Edge)組成的抽象的數(shù)據(jù)結(jié)構(gòu)缭保。結(jié)點(diǎn)和結(jié)點(diǎn)之...
    李威威閱讀 546評(píng)論 0 1
  • 圖分為有向圖汛闸,和無(wú)向圖。 如果圖的邊數(shù)接近頂點(diǎn)數(shù)其為稠密圖 如果圖的邊數(shù)遠(yuǎn)遠(yuǎn)小于頂點(diǎn)數(shù)其為稀疏圖 表示稠密圖一般采...
    一個(gè)人的飄閱讀 500評(píng)論 0 0
  • 圖的表示有兩種: 鄰接矩陣(Adjacency Matrix)和鄰接表(Adjacency Lists) 1艺骂、鄰接...
    濱巖閱讀 162評(píng)論 0 0