Skip to content

Commit f3b822c

Browse files
committed
[Function add]
1.Add conclusion about kosaraju algorithm.
1 parent a52878e commit f3b822c

File tree

5 files changed

+196
-0
lines changed

5 files changed

+196
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package ca.mcmaster.chapter.four.graph.directed;
2+
3+
public interface SCC {
4+
/**
5+
* @Description: Check if v and w are connected.
6+
* @param v
7+
* @param w
8+
* @return
9+
*/
10+
public boolean strongConnected(int v, int w);
11+
/**
12+
* @Description: The number of strong connected component.
13+
* @return
14+
*/
15+
public int count();
16+
/**
17+
* @Description: Which of the strong component belongs to.
18+
* @param v
19+
* @return
20+
*/
21+
int id(int v);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package ca.mcmaster.chapter.four.graph.directed;
2+
3+
public class StrongCircleComponent implements SCC {
4+
private boolean[] marked;
5+
private int[] id;
6+
private int count;
7+
public StrongCircleComponent(Digraph g) {
8+
marked = new boolean[g.V()];
9+
id = new int[g.V()];
10+
DepthFirstOrder order = new DepthFirstOrder(g.reverse());
11+
for(int s : order.reversePost()){ //从栈中顺序读取顶点
12+
if(!marked[s]){
13+
dfs(g, s); count++;
14+
}
15+
}
16+
}
17+
18+
private void dfs(Digraph g, int v){
19+
marked[v] = true;
20+
id[v] = count;
21+
for(int w : g.adj(v))
22+
if(!marked[w])
23+
dfs(g, w);
24+
}
25+
@Override
26+
public boolean strongConnected(int v, int w) {
27+
return id[v] == id[w];
28+
}
29+
30+
@Override
31+
public int count() {
32+
return count;
33+
}
34+
35+
@Override
36+
public int id(int v) {
37+
return id[v];
38+
}
39+
}

DataStructrue/Graph/DirectedGraph.md

+74
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ public class DepthFirstOrder {
392392
### 拓扑排序
393393
>给定一张有向图,将所有的顶点排序,使得所有的有向边均从排在前面的元素指向排在后面的元素。
394394
>有环图画不出拓扑图,因为有环图无法确定环上定点的顺序。
395+
>一幅有向无环图的拓扑顺序即为所有顶点的逆后序排列。
395396
```Java
396397
public class Topological {
397398
private Iterable<Integer> order;
@@ -410,3 +411,76 @@ public class Topological {
410411
}
411412
}
412413
```
414+
415+
### 强连通分量
416+
![强连通分量](https://i.imgur.com/PvMOVvr.jpg)
417+
> 通过对强连通分量的研究可以将不同的对象进行分类,将具有相似性质的对象统一处理。
418+
419+
* 接口
420+
```Java
421+
public interface SCC {
422+
/**
423+
* @Description: Check if v and w are connected.
424+
* @param v
425+
* @param w
426+
* @return
427+
*/
428+
public boolean strongConnected(int v, int w);
429+
/**
430+
* @Description: The number of strong connected component.
431+
* @return
432+
*/
433+
public int count();
434+
/**
435+
* @Description: Which of the strong component belongs to.
436+
* @param v
437+
* @return
438+
*/
439+
int id(int v);
440+
}
441+
```
442+
* Kosaraju算法计算强连通分量
443+
```Java
444+
public class StrongCircleComponent implements SCC {
445+
private boolean[] marked;
446+
private int[] id;
447+
private int count;
448+
public StrongCircleComponent(Digraph g) {
449+
marked = new boolean[g.V()];
450+
id = new int[g.V()];
451+
DepthFirstOrder order = new DepthFirstOrder(g.reverse());//获得g的反转图
452+
for(int s : order.reversePost()){ //按照逆后序读取元素(拓扑图顺序)
453+
if(!marked[s]){
454+
dfs(g, s); count++;
455+
}
456+
}
457+
}
458+
private void dfs(Digraph g, int v){
459+
marked[v] = true;
460+
id[v] = count;
461+
for(int w : g.adj(v))
462+
if(!marked[w])
463+
dfs(g, w);
464+
}
465+
@Override
466+
public boolean strongConnected(int v, int w) {
467+
return id[v] == id[w];
468+
}
469+
@Override
470+
public int count() {
471+
return count;
472+
}
473+
@Override
474+
public int id(int v) {
475+
return id[v];
476+
}
477+
}
478+
```
479+
* Kosaraju证明
480+
1. 每次和s强连通的顶点都会在构造函数调用dfs(g, s)时被访问到。
481+
>反证法:
482+
>假设有一个和s强连通的顶点v不会被访问到,说明v曾经被访问过。
483+
>如果v曾经被访问过,s和v为强连通分量,s应被访问过。
484+
>s当前正在被访问,矛盾。
485+
2. 构造函数dfs(G,s)所到达的任意顶点v都必然是和s强连通的。
486+
>A和B强连通充要条件:A和B在图中连通,B和A在反向图中也连通。

DataStructrue/Graph/SCC.java

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package ca.mcmaster.chapter.four.graph.directed;
2+
3+
public interface SCC {
4+
/**
5+
* @Description: Check if v and w are connected.
6+
* @param v
7+
* @param w
8+
* @return
9+
*/
10+
public boolean strongConnected(int v, int w);
11+
/**
12+
* @Description: The number of strong connected component.
13+
* @return
14+
*/
15+
public int count();
16+
/**
17+
* @Description: Which of the strong component belongs to.
18+
* @param v
19+
* @return
20+
*/
21+
int id(int v);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package ca.mcmaster.chapter.four.graph.directed;
2+
3+
public class StrongCircleComponent implements SCC {
4+
private boolean[] marked;
5+
private int[] id;
6+
private int count;
7+
public StrongCircleComponent(Digraph g) {
8+
marked = new boolean[g.V()];
9+
id = new int[g.V()];
10+
DepthFirstOrder order = new DepthFirstOrder(g.reverse());
11+
for(int s : order.reversePost()){ //从栈中顺序读取顶点
12+
if(!marked[s]){
13+
dfs(g, s); count++;
14+
}
15+
}
16+
}
17+
18+
private void dfs(Digraph g, int v){
19+
marked[v] = true;
20+
id[v] = count;
21+
for(int w : g.adj(v))
22+
if(!marked[w])
23+
dfs(g, w);
24+
}
25+
@Override
26+
public boolean strongConnected(int v, int w) {
27+
return id[v] == id[w];
28+
}
29+
30+
@Override
31+
public int count() {
32+
return count;
33+
}
34+
35+
@Override
36+
public int id(int v) {
37+
return id[v];
38+
}
39+
}

0 commit comments

Comments
 (0)