【问题描述】

给定一个有向图,设计一个算法,求解并输出该图的各个强连通分量。

 package org.xiu68.exp.exp9;

 import java.util.ArrayList;
import java.util.List;
import java.util.Stack; public class Exp9_2 {
public static void main(String[] args) {
int[][] graph=new int[][]{
{0,1,1,0,0},
{1,0,0,0,0},
{0,0,0,1,0},
{0,0,0,0,1},
{0,0,1,0,0}
};
MGraph m1=new MGraph(graph, 5);
m1.getSccs();
}
} class MGraph{
private int[][] graph; //有向图
private int[][] rGraph; //有向图的反向图
private int vexNum; //顶点数量
Stack<Integer> stack; //存储反向图深度优先遍历的post值,从大到小排序 public MGraph(int[][] graph,int vertexNum){
this.graph=graph;
this.vexNum=vertexNum;
stack=new Stack<>();
rGraph=new int[vexNum][vexNum]; //反向图 //求原图的反向图
for(int i=0;i<vexNum;i++){
for(int j=i+1;j<vexNum;j++){
rGraph[i][j]=graph[j][i];
rGraph[j][i]=graph[i][j];
}
}
} public void getSccs(){
rDFSTraverse(); //先对反向图进行深度优先遍历 boolean[] visited=new boolean[vexNum]; //记录深度优先遍历原图过程中已经访问的顶点 List<List<Integer>> sccs=new ArrayList<>(); //存放每一个强连通部件对应的顶点
int n=0; //第几个强连通部件
while(!stack.isEmpty()){
int v=stack.pop();
if(!visited[v]){
sccs.add(new ArrayList<Integer>());
DFS(visited,v,sccs,n);
n++;
}
}
//打印强连通部件
for(int i=0;i<sccs.size();i++){
System.out.print("第"+i+"个强连通部件:");
for(int j=0;j<sccs.get(i).size();j++){
System.out.print(sccs.get(i).get(j)+" ");
}
System.out.println();
}
}
/*
* 对原图进行深度优先遍历
* 在汇点强连通部件中对某个顶点进行深度优先遍历则刚好访问该强连通部件的所有顶点
*/
private void DFS(boolean[] visited,int v,List<List<Integer>> sccs,int n){
sccs.get(n).add(v);
visited[v]=true;
for(int i=0;i<vexNum;i++){
if(graph[v][i]==1 && !visited[i])
DFS(visited,i,sccs,n);
}
} //**************************************************************
/*
* 对反向图进行深度优先遍历,post值最大的顶点将位于反向图中的一个源点强连通部件,
* 也就是原图中的某个汇点连通部件的某个顶点
* 求得各个顶点的post值,压入栈中
*/
public void rDFSTraverse(){
boolean[] visited=new boolean[vexNum];
for(int i=0;i<vexNum;i++){
if(!visited[i]){
rDFS(visited,stack,i);
}
}
}
//对反向图做深度优先遍历
private void rDFS(boolean[] visited,Stack<Integer> stack,int v){
visited[v]=true;
for(int i=0;i<vexNum;i++){
if(rGraph[v][i]==1 && !visited[i]){
rDFS(visited,stack,i);
}
}
stack.push(v);
}
}

最新文章

  1. UICollectionReusableView 使用时的一些问题
  2. javaWeb 使用 filter 处理 html 标签问题
  3. AX Dynamic 2012 SSRS 按行数分页
  4. Mongodb for C# 分组查询
  5. Linux下安装宋体以及微软雅黑字体
  6. Contest20140709 testA 树型DP
  7. kubuntu/ubuntu下安装fcitx输入法
  8. Gson和Json
  9. python编码错误
  10. mongoDB之数据类型
  11. Cannot declare class app\home\controller\Cases because the name is already in use
  12. uva140
  13. Java开发笔记(八十九)缓存字节I/O流
  14. gVim编辑器 模板篇
  15. (转)Spring Boot 2 (八):Spring Boot 集成 Memcached
  16. spring框架等web程序在tomcat下的启动顺序
  17. SpringMVC+SpringJdbc+SQLServer+EasyUI增删改查
  18. nginx实现nginx/tomcat负载均衡
  19. RecyclerView源码解析 - 分割线
  20. 26最短路径之Floyd算法

热门文章

  1. C# String类&amp;Math类&amp;DateTime类
  2. 洛谷P1850 换教室
  3. spring MVC 如何接收前台传入的JSON对象数组
  4. 也谈同步异步I/O
  5. DoubleOps.java
  6. ansible-playbook 变量(vars)
  7. 7、Python-引用传递与值传递
  8. java8的新特性详解-----------Lamda表达式
  9. JS文本框获取焦点
  10. js实用代码段(持续更新)