@@ -392,6 +392,7 @@ public class DepthFirstOrder {
392
392
### 拓扑排序
393
393
> 给定一张有向图,将所有的顶点排序,使得所有的有向边均从排在前面的元素指向排在后面的元素。
394
394
> 有环图画不出拓扑图,因为有环图无法确定环上定点的顺序。
395
+ > 一幅有向无环图的拓扑顺序即为所有顶点的逆后序排列。
395
396
``` Java
396
397
public class Topological {
397
398
private Iterable<Integer > order;
@@ -410,3 +411,76 @@ public class Topological {
410
411
}
411
412
}
412
413
```
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在反向图中也连通。
0 commit comments