程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Kosaraju算法詳解,kosaraju算法

Kosaraju算法詳解,kosaraju算法

編輯:C++入門知識

Kosaraju算法詳解,kosaraju算法


  Kosaraju算法可以求出有向圖中的強連通分量個數,並且對分屬於不同強連通分量的點進行標記。它的算法描述較為簡單: (1) 第一次對圖G進行DFS遍歷,並在遍歷過程中,記錄每一個點的退出順序。以下圖為例:       如果以1為起點遍歷,訪問結點的順序如下:  

 

結點第二次被訪問即為退出之時,那麼我們可以得到結點的退出順序:   (2)倒轉每一條邊的方向,構造出一個反圖G。然後按照退出順序的逆序對反圖進行第二次DFS遍歷。我們按14235的逆序第二次DFS遍歷:  

 

訪問過程如下:   每次遍歷得到的那些點即屬於同一個強連通分量。14屬於同一個強連通分量,235屬於另一個強連通分量。

 代碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int map[101][101];
 6 int nmap[101][101];
 7 int pass[101];
 8 int vis[101];
 9 int now=1;
10 int n,m;
11 int num=0;
12 void dfs(int p)
13 {
14     vis[p]=1;
15     for(int i=1;i<=n;i++)
16     {
17         if(vis[i]==0&&map[p][i]==1)
18         {
19             dfs(i);
20         
21         }
22     }
23     pass[now]=p;
24     now++;
25 }
26 void ndfs(int p)
27 {
28     vis[p]=0;
29     for(int i=1;i<=n;i++)
30     {
31         if(vis[i]==1&&nmap[p][i]==1)
32         ndfs(i);
33     }
34 }
35 int main()
36 {
37     
38     scanf("%d%d",&n,&m);
39     for(int i=1;i<=m;i++)
40     {
41         int x,y;
42         scanf("%d%d",&x,&y);
43         map[x][y]=1;
44         nmap[y][x]=1;
45     }
46     for(int i=1;i<=n;i++)
47     {
48         if(vis[i]==0)
49         dfs(i);
50     }
51     pass[now]=1;
52     for(int i=n;i>=1;i--)
53     {
54         if(vis[pass[i]]==1)
55         {
56             ndfs(pass[i]);
57             num++;
58         }
59     }
60     cout<<num;
61     return 0;
62 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved