010有向图的可达性

图学习笔记索引

图学习笔记索引(全部)
001自定义输入流In类实现
002背包数据类型Bag实现
003无向图数据类型实现
004基于图的深度优先搜索
005使用深度优先搜索找图中的所有连通分量
005-1基于深度优先搜索查找图中连通路径
006基于深度优先搜索判断图中是否存在环
007基于深度优先搜索判断一个无向图图是否是一个二分图
008广度优先搜索查找连通图中的最短路径
009有向图数据类型实现
010有向图的可达性
011带权重的无向边数据类型Edge实现
012加权无向图数据类型实现

本文参考《算法(第4版)》

有向图的可达性

1.从文件中读取图

点击文字获取:流读取类In参考链接
从文件中读取无向图图的顶点关系。
tinyDG.txt文件中的第一行为顶点数,第二行为边数。
第三行到最后是两个相邻的顶点:
13
22
4 2
2 3
3 2
6 0
0 1
2 0
11 12
12 9
9 10
9 11
8 9
10 12
11 4
4 3
3 5
7 8
8 7
5 4
0 5
6 4
6 9
7 6
点击文字获取:背包类Bag参考链接

2.有向图数据类型

package algorithms.graph; 
import java.io.IOException; 
import algorithms.model.Bag; 
/*
 * 有向图数据类型实现
 * 无向图具有对称性,有向图具有有向性
 * */

public class Digraph {
    private final int V;
    private int E;
    private Bag<Integer>[] adj;
    public Digraph(int V){
    	//按边数构造一幅有向图,可通过addEdge()方法添加边
    	this.V = V;
    	this.E = 0;
    	this.adj = (Bag<Integer>[])new Bag[V];
    	for(int v = 0; v < V; v++)
    		adj[v] = new Bag<Integer>();
    }
    public Digraph(In in){
    	//从文件中读取,构造有向图
    	this(in.readInt()); 
    	this.E = 0; //初始化边数
    	int edges = in.readInt(); 
    	for(int i = 0; i < edges; i++){
    		int v = in.readInt();
    		int w = in.readInt();
    		adj[v].add(w); //有向边
    		this.E++;
    	} 
    }
    public int V() { return this.V; }
    public int E() { return this.E; }
    public void addEdge(int v, int w){
    	adj[v].add(w);
    	E++;
    }
    public Iterable<Integer> adj(int v){
    	return adj[v];
    }
    public Digraph reverse(){
    	Digraph R = new Digraph(V);
    	for(int v = 0; v < V; v++) 
    		for(int w : adj[v])
    			R.addEdge(w, v);
    	return R;
    }
    @Override
    public String toString(){
    	String s  = V + " vectors; " + E +" edges" + "\n"; 
    	for(int v = 0; v < V; v++){
    		s += v + ": ";
    		for(int w : adj[v])
    			s += w +" ";
    		s += "\n";
    	} 
		return s;
    }
	public static void main(String[] args) throws IOException {
	    In in = new In("D:\\tinyDG.txt");  
		Digraph D = new Digraph(in);
	    System.out.println(D); 
	    System.out.println(); 
	    //有向图取反
	    System.out.println(D.reverse());
	}

}

输出

13 vectors; 22 edges
0: 5 1 
1: 
2: 0 3 
3: 5 2 
4: 3 2 
5: 4 
6: 9 4 0 
7: 6 8 
8: 7 9 
9: 11 10 
10: 12 
11: 4 12 
12: 9 


13 vectors; 22 edges
0: 6 2 
1: 0 
2: 4 3 
3: 4 2 
4: 11 6 5 
5: 3 0 
6: 7 
7: 8 
8: 7 
9: 12 8 6 
10: 9 
11: 9 
12: 11 10 

3.有向图可达性实现

package algorithms.graph;

import java.io.IOException;

/*
 * 有向图的可达性
 * */
public class DirectedDFS {
	private boolean[] marked;    //该顶点对于起点是否可达
	public DirectedDFS(Digraph D, In source){
		 this.marked = new boolean[D.V()];
		 for(int s : source)
			 if(!marked[s])    
			      dfs(D, s);
	}
	public DirectedDFS(Digraph D, int s){ 
	     this.marked = new boolean[D.V()];
		 if(!marked[s])    
		      dfs(D, s);
	}
	public void dfs(Digraph D, int s){
		marked[s] = true;
		for(int v : D.adj(s))
			if(!marked[v])
				dfs(D, v);
	}
	
	public boolean marked(int v){
		return marked[v];
	}
	public void markedFrom(int s){
		   
	}
	public static void main(String[] args) throws IOException {
		In in = new In("D:\\tinyDG.txt"); 
		Digraph D = new Digraph(in);
		System.out.println(D);  
		
		DirectedDFS d = new DirectedDFS(D, 0);
		System.out.println(d.marked(1));
		
		System.out.println("在有向图中,该顶点是否可达?");  
		DirectedDFS dDFS;
		StringBuilder sb;
		for(int s = 0; s < D.V(); s++){
			dDFS = new DirectedDFS(D, s);
			sb = new StringBuilder();
			for(int w = 0; w < D.V(); w++) {
		    	if(dDFS.marked[w])
		    		sb.append(w);
		    	sb.append(","); 
		    }
			System.out.println(s + "可达的顶点: " + sb.toString());   
		} 
	} 
}

输出:

13 vectors; 22 edges
0: 5 1 
1: 
2: 0 3 
3: 5 2 
4: 3 2 
5: 4 
6: 9 4 0 
7: 6 8 
8: 7 9 
9: 11 10 
10: 12 
11: 4 12 
12: 9 

true
在有向图中,该顶点是否可达?
0可达的顶点: 0,1,2,3,4,5,,,,,,,,
1可达的顶点: ,1,,,,,,,,,,,,
2可达的顶点: 0,1,2,3,4,5,,,,,,,,
3可达的顶点: 0,1,2,3,4,5,,,,,,,,
4可达的顶点: 0,1,2,3,4,5,,,,,,,,
5可达的顶点: 0,1,2,3,4,5,,,,,,,,
6可达的顶点: 0,1,2,3,4,5,6,,,9,10,11,12,
7可达的顶点: 0,1,2,3,4,5,6,7,8,9,10,11,12,
8可达的顶点: 0,1,2,3,4,5,6,7,8,9,10,11,12,
9可达的顶点: 0,1,2,3,4,5,,,,9,10,11,12,
10可达的顶点: 0,1,2,3,4,5,,,,9,10,11,12,
11可达的顶点: 0,1,2,3,4,5,,,,9,10,11,12,
12可达的顶点: 0,1,2,3,4,5,,,,9,10,11,12,

4.总结

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值