Ex3_15 判断图是否是一个强连通分量 判断点是否在汇点强连通分量中_十一次作业
(a) 可以用图中的每一个顶点表示街道中的每个十字路口,由于街道都是单行的,所以图是有向图,若从一个十字路口都有一条合法的路线到另一个十字路口,则图是一个强连通图。即要验证的是图是否是一个强连通图。
(b) 若从市政厅沿着合法路线到达任何一个地方都有合法路线返回则说明市政厅位于一个有向图中的一个汇点强连通部件中。
package org.xiu68.ch03.ex11; import java.util.ArrayList;
import java.util.List;
import java.util.Stack; public class Ex3_15 { public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] edges=new int[][]{
{0,1,0,0},
{0,0,1,0},
{0,0,0,1},
{1,0,0,0}
};
MGraph1 m1=new MGraph1(edges);
m1.checkSC(0); //强连通图 System.out.println("***************************");
int[][] edges1=new int[][]{
{0,1,0,1},
{0,0,1,0},
{0,0,0,1},
{0,0,0,0}
};
MGraph1 m2=new MGraph1(edges1);
m2.checkSC(0);
for(int i=0;i<4;i++){
System.out.print(i+":");
m2.isInSinkSCC(i);
}
//输出
/*
非强连通图
0:不存在汇点强连通分量中
1:不存在汇点强连通分量中
2:不存在汇点强连通分量中
3:存在汇点强连通分量中
*/ System.out.println("***************************");
int[][] edges3=new int[][]{
{0,0,0,0,0,0,0},
{1,0,0,1,0,0,0},
{1,0,0,1,0,0,0},
{0,0,0,0,1,1,0},
{0,0,0,1,0,0,1},
{0,0,0,1,0,0,1},
{0,0,0,0,1,1,0}
};
MGraph1 m3=new MGraph1(edges3);
for(int i=0;i<edges3.length;i++){
System.out.print(i+":");
m3.isInSinkSCC(i);
}
//输出
/*
0:存在汇点强连通分量中
1:不存在汇点强连通分量中
2:不存在汇点强连通分量中
3:存在汇点强连通分量中
4:存在汇点强连通分量中
5:存在汇点强连通分量中
6:存在汇点强连通分量中
*/
} } class MGraph1{
private int[][] edges; //有向图
private int[][] rEdges; //有向图的反向图
private int vexNum; //顶点数量
private Stack<Integer> stack; //存储反向图深度优先遍历的post值 public MGraph1(int[][] edges){
this.edges=edges;
this.vexNum=edges.length;
stack=new Stack<>();
rEdges=new int[vexNum][vexNum]; //反向图 //求原图的反向图
for(int i=0;i<vexNum;i++){
for(int j=i+1;j<vexNum;j++){
rEdges[i][j]=edges[j][i];
rEdges[j][i]=edges[i][j];
}
} }
//******************************************************
//验证图是否是强连通的
/*
* 先从某个顶点开始对原图进行深度优先遍历
* 再从这个顶点开始对反向图做深度优先遍历
* 若两次遍历都能访问所有顶点说明是强连通图
*/
public void checkSC(int v){
boolean[] visited=new boolean[vexNum]; //原图中已访问的顶点
dfs(edges,visited,v); boolean[] rVisited=new boolean[vexNum]; //反向图中已访问的顶点
dfs(rEdges,rVisited,v); for(int i=0;i<vexNum;i++){
if(!visited[i] || !rVisited[i]){
System.out.println("非强连通图");
return;
}
}
System.out.println("强连通图");
} //深度优先遍历
public void dfs(int[][] edges,boolean[] visited,int v){
visited[v]=true;
for(int i=0;i<vexNum;i++){
if(edges[v][i]==1 && !visited[i]){
dfs(edges,visited,i);
}
}
}
//**************************************************************
//判断一个顶点是否位于一个汇点强连通部件中
public void isInSinkSCC(int target){
rDFSTraverse(); //先对反向图进行深度优先遍历 //List<List<Integer>> sccs=new ArrayList<>(); //存放每一个强连通部件对应的顶点 boolean[] visited=new boolean[vexNum]; //记录深度优先遍历原图过程中非当前强连通分量已经访问的顶点
int[] visitedN=new int[vexNum]; //记录顶点属于第几个强连通分量
boolean[] isSinkSCC=new boolean[vexNum]; //记录第i个强连通分量是否是汇点强连通部件,最多有vexNum个强连通部件
int n=0; //第几个强连通部件 for(int i=0;i<vexNum;i++){
visitedN[i]=-1;
isSinkSCC[i]=true;
} while(!stack.isEmpty()){
int v=stack.pop();
if(!visited[v]){
//sccs.add(new ArrayList<Integer>());
List<Integer> vexs=new ArrayList<>(); //记录第n个强连通分量的顶点 DFS(visited,visitedN,v,vexs,isSinkSCC,n);
for(int i=0;i<vexs.size();i++){
//sccs.get(i).add(vexs.get(i));
visited[vexs.get(i)]=true;
}
n++;
}
}
if(isSinkSCC[visitedN[target]]){
System.out.println("存在汇点强连通分量中");
}else{
System.out.println("不存在汇点强连通分量中");
}
}
/*
* 对原图进行深度优先遍历
* 在汇点强连通部件中对某个顶点进行深度优先遍历则刚好访问该强连通部件的所有顶点
*/
private void DFS(boolean[] visited,int[] visitedN,int v,/*List<List<Integer>> sccs,*/
List<Integer> vexs,boolean[] isSinkSCC,int n){
//sccs.get(n).add(v);
vexs.add(v);
visitedN[v]=n;
for(int i=0;i<vexNum;i++){
if(edges[v][i]==1){
//若在一个汇点强连通部件中进行深度优先遍历,刚好得到该汇点强连通部件
//若遍历到其他强连通分量的顶点说明该强连通分量不是汇点强连通分量
if(visited[i]){
isSinkSCC[n]=false;
}else if(visitedN[i]!=n){
DFS(visited,visitedN,i,/*sccs,*/vexs,isSinkSCC,n);
}
}
}//for
} //**************************************************************
/*
* 对反向图进行深度优先遍历,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(rEdges[v][i]==1 && !visited[i]){
rDFS(visited,stack,i);
}
}
stack.push(v);
}
}
Ex3_15 判断图是否是一个强连通分量 判断点是否在汇点强连通分量中_十一次作业的更多相关文章
- Ex 3_25 图中每个顶点有一个相关价格..._十一次作业
(a)首先对有向无环图进行拓扑排序,再按拓扑排序的逆序依次计算每个顶点的cost值,每个顶点的cost值为自身的price值与相邻顶点间的cost值得最小值 (b)求出图中的每一个强连通分量,并把所有 ...
- ViewPager 滑动一半的判断方法以及左滑右滑判断
做项目的时候,会碰到用viewpager + fragments去实现多页滑动.有些时候需要完成:界面在滑动到一半或是一半以上的时候,需要把title之类的切换到下一个页面.这个时候仅仅依赖Viewp ...
- POJ 1860 Currency Exchange(如何Bellman-Ford算法判断图中是否存在正环)
题目链接: https://cn.vjudge.net/problem/POJ-1860 Several currency exchange points are working in our cit ...
- 判断图连通的三种方法——dfs,bfs,并查集
Description 如果无向图G每对顶点v和w都有从v到w的路径,那么称无向图G是连通的.现在给定一张无向图,判断它是否是连通的. Input 第一行有2个整数n和m(0 < n,m < ...
- POJ_1064_Cable_master_(二分,假定一个解并判断是否可行)
描述 http://poj.org/problem?id=1064 有n条绳子,长度分别为l[i].如果从它们中切割出k条长度相同的绳子的话,这k条绳子每条最长能有多少? Cable master T ...
- 金牌分析师助力 鲁泰A图谋再造一个“鲁泰”?_财经_中国网
金牌分析师助力 鲁泰A图谋再造一个"鲁泰"?_财经_中国网 金牌分析师助力 鲁泰A图谋再造一个"鲁泰"?
- 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...
- Github作为图床的一个小坑
Github作为图床的一个小坑 前言 听了少铭同学建议把github作为图床,结果遇到了一个小坑,总是显示不出来图片. 问题描述与解决 形如下的链接是显示不出来的: https://github.co ...
- HDU-1232 畅通工程 (并查集、判断图中树的棵数)
Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相 ...
随机推荐
- jquery&bootstrap
学会了用bootstarp和jquery的引用,布局就简单多了,但就是不怎么自由,必须按照固定的来: 引用文件: <script type="text/javascript" ...
- javascript:location.reload()和location.replace()的区别,及对图片缓存的影响。
有段时间没有清理IE的临时文件(缓存文件),在我清理的时候,我突然发现一个问题. 我打开的一个网站,图片默认缓存一个月的,但我发现,当我上传图片或删除图片之后,图片重新缓存,也就意味着,在我上传新图片 ...
- gcc-linaro-arm-linux-gnueabihf交叉编译器配置
系统Ubuntu14.04 版本:gcc 版本 4.7.3 20130328 (prerelease) (crosstool-NG linaro-1.13.1-4.7-2013.04-20130415 ...
- 1024. Palindromic Number (25)
A number that will be the same when it is written forwards or backwards is known as a Palindromic Nu ...
- 即将上线的Kafka服务器面临的一系列填坑笔记
即将上线的Kafka服务器面临的一系列填坑笔记 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Kafka日志报错:[error] k.m.j.KafkaJMX$ - Fai ...
- 在tomcat集群下利用redis实现单点登陆
场景:比如说我们要实现一个集群环境,无非是把多个项目部署到多个tomcat下,然后按照一定的算法,轮询什么的随机访问多个tomcat服务器,但是问题也会有许多,比如说,我们最开始是把登陆人的信息存放到 ...
- JAVA记录-SpringMVC scope属性的两种模式
singleton作用域:当把一个Bean定义设置为singleton作用域是,Spring IoC容器中只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean定义相匹配,则只 ...
- baiduTemplate.js 百度JS模板引擎
baiduTemplate希望创造一个用户觉得“简单好用”的JS模板引擎 先展示两个例子,然后说说对baidutemplate.js的理解,从而将这一工具加到个人百宝箱里. <script id ...
- datagrid点删除,弹出一个确认和取消的消息框
有个简单的方法:在datagrid的删除按扭datagrid的属性生成器->列->添加按扭列->删除在数据字段中加上:<div id="de" onclic ...
- 网络类型IPv4和IPv6什么意思?区别?
在windows 7以上系统中,在设置本地IP地址的时候经常会看到同事含有IPV4协议项与IPV6协议项,并不同于以往windows xp系统中仅有TCP/IP协议项,不少朋友都觉得比较奇怪,询问编辑 ...