强连通分量算法
Kosaraju算法 ,Targen算法(递归) c#
1
代码
1 /*
2 * User: Answer
3 * Date: 2010-04-13
4 * Time: 21:58
5 */
6 using System;
7 using System.IO;
8 using System.Collections;
9 using System.Text;
10
11 namespace Graph
12 {
13 /// <summary>
14 /// Description of SCCKosaraju.
15 /// </summary>
16 public class SCCKosaraju
17 {
18 ArrayList[] adja; // adjacency list
19 ArrayList[] Radja; // reverse adjacency list
20 bool[] visited;
21 Stack stack;
22 int count = 1;
23
24 public SCCKosaraju(ArrayList[] adja)
25 {
26 this.adja = adja;
27 this.Radja = ReverseAdjacencyList(adja);
28 this.stack = new Stack();
29 visited = new bool[adja.Length];
30
31 }
32 private ArrayList[] ReverseAdjacencyList(ArrayList[] adja)
33 {
34 ArrayList[] r = new ArrayList[adja.Length];
35 for(int i=0;i<adja.Length;i++) {
36 foreach(int node in adja[i]) {
37 if(r[node] == null)
38 r[node] = new ArrayList();
39 r[node].Add(i);
40 }
41 }
42 return r;
43
44 }
45
46 public void DFS ( int node )
47 {
48 visited[node] = true;
49 foreach(int nei in adja[node]) {
50 if(!visited[nei]){
51
52 DFS(nei);
53 }
54 }
55 stack.Push(node);
56
57 }
58
59 public void DFS2 ( int node )
60 {
61 visited[node] = true;
62 Console.WriteLine("{0}:{1}",node,count);
63 foreach(int nei in Radja[node] ) {
64 if(!visited[nei]) {
65
66 DFS2(nei);
67 }
68 }
69 }
70
71 public void start ()
72 {
73
74 for(int i = 0;i<adja.Length;i++){
75 if ( !visited[i])
76 DFS(i);
77 }
78
79 Array.Clear(visited,0,visited.Length);
80
81 while(stack.Count != 0) {
82 int node = (int)stack.Pop();
83 if(!visited[node]) {
84 DFS2(node);
85 count++;
86 }
87 }
88 }
89 public static void Main(string[] args)
90 {
91 ArrayList l1 = new ArrayList(){1,2};
92 ArrayList l2 = new ArrayList(){3};
93 ArrayList l3 = new ArrayList(){3,4};
94 ArrayList l4 = new ArrayList(){0,5};
95 ArrayList l5 = new ArrayList(){5};
96 ArrayList l6 = new ArrayList(){};
97 ArrayList[] edge = new ArrayList[]{l1,l2,l3,l4,l5,l6};
98
99 new SCCKosaraju(edge).start();
100 Console.Write("END. ");
101 Console.ReadKey(true);
102 }
103
104 }
105 }
106
2 * User: Answer
3 * Date: 2010-04-13
4 * Time: 21:58
5 */
6 using System;
7 using System.IO;
8 using System.Collections;
9 using System.Text;
10
11 namespace Graph
12 {
13 /// <summary>
14 /// Description of SCCKosaraju.
15 /// </summary>
16 public class SCCKosaraju
17 {
18 ArrayList[] adja; // adjacency list
19 ArrayList[] Radja; // reverse adjacency list
20 bool[] visited;
21 Stack stack;
22 int count = 1;
23
24 public SCCKosaraju(ArrayList[] adja)
25 {
26 this.adja = adja;
27 this.Radja = ReverseAdjacencyList(adja);
28 this.stack = new Stack();
29 visited = new bool[adja.Length];
30
31 }
32 private ArrayList[] ReverseAdjacencyList(ArrayList[] adja)
33 {
34 ArrayList[] r = new ArrayList[adja.Length];
35 for(int i=0;i<adja.Length;i++) {
36 foreach(int node in adja[i]) {
37 if(r[node] == null)
38 r[node] = new ArrayList();
39 r[node].Add(i);
40 }
41 }
42 return r;
43
44 }
45
46 public void DFS ( int node )
47 {
48 visited[node] = true;
49 foreach(int nei in adja[node]) {
50 if(!visited[nei]){
51
52 DFS(nei);
53 }
54 }
55 stack.Push(node);
56
57 }
58
59 public void DFS2 ( int node )
60 {
61 visited[node] = true;
62 Console.WriteLine("{0}:{1}",node,count);
63 foreach(int nei in Radja[node] ) {
64 if(!visited[nei]) {
65
66 DFS2(nei);
67 }
68 }
69 }
70
71 public void start ()
72 {
73
74 for(int i = 0;i<adja.Length;i++){
75 if ( !visited[i])
76 DFS(i);
77 }
78
79 Array.Clear(visited,0,visited.Length);
80
81 while(stack.Count != 0) {
82 int node = (int)stack.Pop();
83 if(!visited[node]) {
84 DFS2(node);
85 count++;
86 }
87 }
88 }
89 public static void Main(string[] args)
90 {
91 ArrayList l1 = new ArrayList(){1,2};
92 ArrayList l2 = new ArrayList(){3};
93 ArrayList l3 = new ArrayList(){3,4};
94 ArrayList l4 = new ArrayList(){0,5};
95 ArrayList l5 = new ArrayList(){5};
96 ArrayList l6 = new ArrayList(){};
97 ArrayList[] edge = new ArrayList[]{l1,l2,l3,l4,l5,l6};
98
99 new SCCKosaraju(edge).start();
100 Console.Write("END. ");
101 Console.ReadKey(true);
102 }
103
104 }
105 }
106
2
代码
/*
* User: Answer
* Date: 2010-04-12
* Time: 21:53
*
*/
using System;
using System.Collections;
using System.IO;
namespace Graph
{
/// <summary>
/// Description of SCC.
/// </summary>
public class SCCTargen
{
private int[] SCCnum;
private int[] index;
private int[] back;
private Stack stack;
private ArrayList[] adja;
private int step = 1;
private int count = 1;
public SCCTargen(ArrayList[] adja)
{
this.adja = adja;
this.index = new int[adja.Length];
this.back = new int[adja.Length];
this.SCCnum = new int[adja.Length];
stack = new Stack();
}
public void start()
{
for(int i=0;i<index.Length;i++) {
if(index[i] == 0)
Targen(i);
}
// Save the results
//StreamWriter w = new StreamWriter("");
for(int i=0;i<SCCnum.Length;i++) {
Console.WriteLine("NODE {0} :{1} ",i+1,SCCnum[i]);
}
}
public void Targen(int node)
{
stack.Push(node);
index[node] = step;
back[node] = step++;
foreach(int nei in (ArrayList)adja[node]) {
if(index[nei] == 0 ) { //neighbor isnot visited
Targen(nei);
if(back[node] > back[nei])
back[node] = back[nei];
} else if(stack.Contains(nei)){
if(index[nei] < back[node])
back[node] = index[nei];
}
}
if(index[node] == back[node]) {
int x = 0;
do{
x = (int)stack.Pop();
SCCnum[x] = count;
}while(x != node);
count ++;
}
}
public static void Main(string[] args)
{
ArrayList l1 = new ArrayList(){1,2};
ArrayList l2 = new ArrayList(){3};
ArrayList l3 = new ArrayList(){3,4};
ArrayList l4 = new ArrayList(){0,5};
ArrayList l5 = new ArrayList(){5};
ArrayList l6 = new ArrayList(){};
ArrayList[] edge = new ArrayList[]{l1,l2,l3,l4,l5,l6};
new SCCTargen(edge).start();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
* User: Answer
* Date: 2010-04-12
* Time: 21:53
*
*/
using System;
using System.Collections;
using System.IO;
namespace Graph
{
/// <summary>
/// Description of SCC.
/// </summary>
public class SCCTargen
{
private int[] SCCnum;
private int[] index;
private int[] back;
private Stack stack;
private ArrayList[] adja;
private int step = 1;
private int count = 1;
public SCCTargen(ArrayList[] adja)
{
this.adja = adja;
this.index = new int[adja.Length];
this.back = new int[adja.Length];
this.SCCnum = new int[adja.Length];
stack = new Stack();
}
public void start()
{
for(int i=0;i<index.Length;i++) {
if(index[i] == 0)
Targen(i);
}
// Save the results
//StreamWriter w = new StreamWriter("");
for(int i=0;i<SCCnum.Length;i++) {
Console.WriteLine("NODE {0} :{1} ",i+1,SCCnum[i]);
}
}
public void Targen(int node)
{
stack.Push(node);
index[node] = step;
back[node] = step++;
foreach(int nei in (ArrayList)adja[node]) {
if(index[nei] == 0 ) { //neighbor isnot visited
Targen(nei);
if(back[node] > back[nei])
back[node] = back[nei];
} else if(stack.Contains(nei)){
if(index[nei] < back[node])
back[node] = index[nei];
}
}
if(index[node] == back[node]) {
int x = 0;
do{
x = (int)stack.Pop();
SCCnum[x] = count;
}while(x != node);
count ++;
}
}
public static void Main(string[] args)
{
ArrayList l1 = new ArrayList(){1,2};
ArrayList l2 = new ArrayList(){3};
ArrayList l3 = new ArrayList(){3,4};
ArrayList l4 = new ArrayList(){0,5};
ArrayList l5 = new ArrayList(){5};
ArrayList l6 = new ArrayList(){};
ArrayList[] edge = new ArrayList[]{l1,l2,l3,l4,l5,l6};
new SCCTargen(edge).start();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}