有向图基础

0:有向图基础类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package  Digraph;
 
import  java.util.ArrayList;
 
//有向图
public  class  Digraph {
     private  final  int  v; //顶点数
     private  int  E; //边数
     private  ArrayList<ArrayList<Integer>> adj; //邻接表
     
     public  Digraph( int  v){ //v个顶点的图
         this .v = v;
         this .E =  0 ;
         
         adj =  new  ArrayList<>();
         for ( int  i= 0 ;i<v;i++)
             adj.add( new  ArrayList<Integer>());
     }
         
     //添加边 
     public  void  addEdge( int  u, int  v){
         adj.get(u).add(v);
         E++;
     }
     
     //取顶点v可以直接到达的点
     public  ArrayList<Integer> getAdj( int  v){
         return  adj.get(v);
     }
     
     
     //取反向图。所有边的方向变反。
     public  Digraph reverse(){
         Digraph g =  new  Digraph(v);
         for ( int  i= 0 ;i<v;i++){
             for  (Integer ele : getAdj(i)) {
                 g.addEdge(ele,i);
             }
         }
         
         return  g;
     }
     
     public  int  getV(){
         return  v;
     }
     public  int  getE(){
         return  E;
     }
     
}
1:有向图的  可达性:  无向图的  连通性:
2:多点可达性:是否存在一条从顶点集合中的任意顶点到达给定顶点v的有向路径.
    应用: 如java的内存回收机制.对象为顶点,引用为边.无法被访问到的对象被回收内存.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package  Digraph;
 
import  java.util.ArrayList;
 
//有向图的可达性
public  class  DirectedDFS {
     private  boolean [] isVisited; //
     
     public  DirectedDFS(Digraph G, int  s){ //图G中从s可达的所有顶点
         isVisited =  new  boolean [G.getV()];
         dfs(G,s);
     }
 
     //在G中找出从sources中的所有顶点可达的所有顶点
     public  DirectedDFS(Digraph G,ArrayList<Integer> source){
         isVisited =  new  boolean [G.getV()];
         for (Integer u : source){
             if (!isVisited[u]) dfs(G, u);
         }
     }
     //深度优先搜索
     private  void  dfs(Digraph G,  int  s) {
         isVisited[s] =  true ;
         for  (Integer v : G.getAdj(s)) {
             if (!isVisited[v]){
                 dfs(G, v);
             }
         }
     }
     
     //v是否可达
     public  boolean  marked( int  v){
         return  isVisited[v];
     }
     
}

3:有向图中的环:
     如果一个优先级限制问题中存在有向环,那么这个问题肯定是无解的.

4:寻找有向环.   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package  Digraph;
 
import  java.util.LinkedList;
//判断有向图是否有环.
 
public  class  DirectedCycle {
     private  boolean [] isVisted; //顶点访问状态
     private  int [] edgeTo;  //顶点父子关系
     private  LinkedList<Integer> cycle; //有向环中的多有顶点
     private  boolean [] onStack;  //递归调用栈上的所有顶点. 
     
     public  DirectedCycle(Digraph G){
         onStack =  new  boolean [G.getV()];
         isVisted =  new  boolean [G.getV()];
         edgeTo =  new  int [G.getV()];
         for ( int  v= 0 ;v<G.getV();v++){
             if (!isVisted[v]) dfs(G,v);
         }
     }
     
     //dfs判断有向图是否有环
     private  void  dfs(Digraph G, int  v){
         onStack[v] =  true ;
         isVisted[v] =  true ;
         
         for (Integer w : G.getAdj(v)){
             if ( this .hasCycle())  return ; //如果已经找到环,则退出dfs递归
             else  if (!isVisted[w]){
                 edgeTo[w] = v; //顶点w的前驱为v 
                 dfs(G, w);
             }
             else  if (onStack[w]){ //w已经被访问过,所以有环
                 cycle =  new  LinkedList<>();
                 for ( int  x = v; x!=w;x=edgeTo[x]){ //环的轨迹
                     cycle.push(x);
                 }
                 
                 cycle.push(w); //环的起点
                 cycle.push(v); //环的终点
             }
         }
  onStake[v] = false;//当这条路径到死胡同的时候.退栈.这样在dfs下条路径的时候onStack等于被重新初始化.
     }
 
     private  boolean  hasCycle() {
         return  cycle !=  null ;
     }
}
5:(1)拓扑排序:给定一幅有向图,将所有的顶点排序,使得所有的有向边均从排在前边的元素指向排在后边的元素.
     (2)优先级限制下的调度问题等价于计算有向无环图中的所有顶点和拓扑排序。
     (3)有向无环图才可以进行拓扑排序。
     (4)前序序列就是dfs()的调用顺序,后序序列就是顶点遍历完成的顺序。
     (5)拓扑排序即为所有顶点的逆后序排列(与后序序列相反)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package  Digraph;
 
import  java.util.LinkedList;
//有向图基于深度优先搜索的顶点顺序
public  class  DepthFirstOrder {
     private  boolean [] isVisited;
     private  LinkedList<Integer> pre; //先序
     private  LinkedList<Integer> post; //后序
     private  LinkedList<Integer> reversePost; //逆后序
     
     public  DepthFirstOrder(Digraph G){
         pre  =  new  LinkedList<>();
         post =  new  LinkedList<>();
         reversePost =  new  LinkedList<>();
         
         isVisited =  new  boolean [G.getV()];
         
         for ( int  v= 0 ;v<G.getV();v++){
             if (!isVisited[v]) dfs(G,v);
         }
     }
 
     //递归求各顶点顺序
     private  void  dfs(Digraph g,  int  v) {
         isVisited[v] =  true ;
         pre.add(v); //先序
         
         for ( int  w : g.getAdj(v)){
             if (!isVisited[w]){ 
                 dfs(g, w);
             }
         }      
         
         post.add(v); //后序
         reversePost.push(v); //逆后序
     }
 
     public  LinkedList<Integer> getPre() {
         return  pre;
     }
 
     public  void  setPre(LinkedList<Integer> pre) {
         this .pre = pre;
     }
 
     public  LinkedList<Integer> getPost() {
         return  post;
     }
 
     public  void  setPost(LinkedList<Integer> post) {
         this .post = post;
     }
 
     public  LinkedList<Integer> getReversePost() {
         return  reversePost;
     }
 
     //逆后序即为拓扑排序
     public  void  setReversePost(LinkedList<Integer> reversePost) {
         this .reversePost = reversePost;
     }
}
 
6:有向图的顶点对可达性,即u到v的可达性。 值几个用dfs即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package  Digraph;
//顶点对的可达性
public  class  TransitiveClosure {
     private  DirectedDFS[] all; //邻接矩阵,表明v到w是否可达
     
     public  TransitiveClosure(Digraph G){
         all =  new  DirectedDFS[G.getV()];
         
         for ( int  i= 0 ;i<G.getV();i++){
             all[i] =  new  DirectedDFS(G,i);
         }
     }
     //v到w是否可达
     public  boolean  reachable( int  v, int  w){
         return  all[v].marked(w);
     }
}   

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值