典型演算法與ACM題目解析 02 有向圖的強連通分量

2022-12-20 10:15:06 字數 2595 閱讀 8706

圖的強連通分量

中優先佇列的用法

作者:dzf閱讀次數:87時間:2006-11-27 21:23:49演算法園地

這道題是poj的2186題,

題意是說,有一群牛,總數為n(n<=10000),題目資料給出牛之間的

關係,比如說1仰慕2,2仰慕3等等,設這種仰慕是可以傳遞的,如果1仰慕2,那麼1也會同時仰慕2仰慕的那些牛,如果一頭牛被所有的牛都仰慕,那麼它將是最受歡迎的牛,題目要

求的是有多少牛是"最受歡迎的"。

這道題目大家第一眼看到可能感覺直接模擬,但是由於資料量巨大,模擬的話肯定是過不

了的,而且題目中還會出現環路的情況,比如1=>2,2=>3,3=>1,所以這解這道題最好的方

法是使用有向圖的強連通分量。

在同乙個強連通分量裡的所有的牛之間是互相仰慕的,我們將其縮為一點,並且只記錄這

一點的牛的數量,如果有最受歡迎的牛存在,那麼這個圖將是連通圖,並且出度為零的點

只有乙個,我們可以用並查集來判是否連通,然後計算每個節點的出度,即可求出最受歡

迎的牛的數量。

求強連通分量有三種演算法,分別是kosaraju演算法,gabow演算法和tarjan演算法,其中kosaraju

演算法要對原圖和逆圖都進行一次dfs,而另外兩種演算法只要dfs一次就可以了用了gabow演算法和kosaraju演算法各寫了一遍

在時間上gabow演算法是122ms,kosaraju演算法是61ms

理論上gabow演算法要比kosaraju快些的,因為gabow演算法只對原圖進行一次dfs

而kosaraju要進行兩次

gabow反而慢的原因可能是我用了stl裡的stack

ps:我沒看懂gabow演算法,完全是對著書上寫的**如下:kosaraju演算法

/*求有向圖的強連通分量的kosaraju『s algorithmby sempr ---- 2006.06.16*/

#include <>#include <>#define g_size 100000#define v_size 11000typedef struct graph graph;

typedef struct edge edge;

edge e[g_size];

graph ga[g_size], gt[g_size];int n, m;int g_end;

int order[v_size], id[v_size], vis[v_size], in[v_size];int cnt, scnt, pos;

void insert(int s, int e) //建立原圖和逆圖

void dfst(int x) //對逆圖進行搜尋

order[cnt++] = x;}

void dfsa(int x) //對原圖進行搜尋}

void solve() //主要過程

memset(vis, 0, sizeof(vis));cnt = 0;

for (i = 0; i < n; i++)}

memset(vis, 0, sizeof(vis));cnt = 0;

for (i = n - 1; i >= 0; i--)}

for (i = 0; i < m; i++)}

scnt = cnt;cnt = 0;

for (i = 0; i < scnt; i++)}

if (cnt != 1)else}

printf("%d\n", cnt);}}

int main()

gabow演算法/*

求有向圖的強連通分量的gabow『s algorithmby sempr ---- 2006.06.14*/

#include <>#include #include #define size 11000using namespace std;int n, m;

typedef struct node node;

typedef struct edgeedge;

edge e[size * 6];node g[size * 7];

int pre[size], id[size];typedef stack stack;stack s, path;int end;

int cnt, scnt;int vis[size];int in[size];

void insert(int s, int e)}

g[p].next = end;g[end].id = e;end++;}

void scr(int w)

void gabow()}}

void dfs(int w, int d)

while (p)

p = g[p].next;}}

void solve()

gabow();

memset(g, 0, sizeof(g));

memset(pre, 0, sizeof(pre));end = scnt + 10;

for (i = 0; i < m; i++)}

cnt = 0;

for (i = 0; i < scnt; i++)}

if (cnt != 1)else}

printf("%d\n", cnt);}}

int main()

return 0;}

《ACM程式設計與演算法》課程報告

2010 2011學年第2學期 acm程式設計與演算法 課程報告 班級 電氣0903 學號 20095690 姓名 劉星 格雷碼問題解題報告 一 研究報告 80分 1.題目描述 10分 在數字系統中只能識別0和1,各種資料要轉換為二進位制 才能進行處理,格雷碼是一種無權碼,採用絕對編碼方式,典型格雷...

演算法框圖 複數 推理與證明階段性測試題及解析

本試卷分第 卷 選擇題 和第 卷 非選擇題 兩部分 滿分150分 考試時間120分鐘 第 卷 選擇題共60分 一 選擇題 本大題共12個小題,每小題5分,共60分,在每小題給出的四個選項中,只有一項是符合題目要求的 1 2015 豫南九校聯考 複數的實部與虛部之和為 a 0 b 1 c 2 d 3 ...

甘肅省2023年公務員面試真題題目與解析

甘肅省2009年公務員面試真題題目與解析 名言人生哲理類 甘肅省2009面試公務員面試工作已經結束。甘肅省2009面試公務員面試真題主要集中在名言人生哲理 活動組織及疑難問題處理 對社會現象的看法與分析 個人情況與職務匹配四個方面。名言人生哲理類題目偏難,活動組織是常見題目比較簡單,疑難問題處理類難...