Six applications of depth-first traversal of graphs with Java code

Table of Contents

The number of connected components of an undirected graph

Simply find the number of connected components

Can we specifically return which points are the same connected component?

path problem

Single source path problem

Path problem from one vertex to another vertex

Detecting cycles in undirected graphs

Detection of bipartite graphs


Number of connected components of undirected graph

The number of connected components is simply found

import java.util.ArrayList;

public class CC {

    private Graph G;
    private int[] visited;
    private int cccount = 0;

    public CC(Graph G){

        this.G = G;
        visited = new int[G.V()];
        for(int i = 0; i < visited.length; i + + )
            visited[i] = -1;

        for(int v = 0; v < G.V(); v + + )
            if(visited[v] == -1){
                dfs(v,cccount);
                cccount + + ;
            }
    }

    private void dfs(int v, int ccid){

        visited[v] = ccid;
        for(int w: G.adj(v))
            if(visited[w] == -1)
                dfs(w, ccid);
    }

    public int count(){
// for(int e: visited)
// System.out.print(e + " ");
// System.out.println();
        returncccount;
    }

    public boolean isConnected(int v, int w){
        G.validateVertex(v);
        G.validateVertex(w);
        return visited[v] == visited[w];
    }

    public ArrayList<Integer>[] components(){

        ArrayList<Integer>[] res = new ArrayList[cccount];
        for(int i = 0; i < cccount; i + + )
            res[i] = new ArrayList<Integer>();

        for(int v = 0; v < G.V(); v + + )
            res[visited[v]].add(v);
        return res;
    }

    public static void main(String[] args){

        Graph g = new Graph("g.txt");
        CC cc = new CC(g);
        System.out.println(cc.count());

        System.out.println(cc.isConnected(0, 6));
        System.out.println(cc.isConnected(5, 6));

        ArrayList<Integer>[] comp = cc.components();
        for(int ccid = 0; ccid < comp.length; ccid + + ){
            System.out.print(ccid + " : ");
            for(int w: comp[ccid])
                System.out.print(w + " ");
            System.out.println();
        }
    }
}

Which points can be returned specifically as the same connected component

import java.util.ArrayList;

public class CC{
  private Graph G;
  private boolean[] visited;
  private int cccount = 0;
public CC(Graph G){
    this.G = G;
  visited = new int[G.V()];
for(int i = 0; i < visited.length; i + + )
{
         visited[i] = -1;
}
for(int v = 0; v < G.V(); v + + ){
   if(visited[V] == -1){
      dfs(v, count);
      cccount + + ;
   }
  }
private void dfs(int v, int ccid){
   visited[v] = ccid;
for(int w : G.adj(v)){
   if(visited[w] == -1){
       dfs(w, ccid);
    }
   }
  }
public int count(){
   for(int e : visited){
    System.out.print(e + " ");
}
   System.out.println();
   returncccount;
  }
public static void main(String[] args){
 Graph g = new Graph("g.txt");
 CC cc = new GraphDFS(g);
 System.out.println(cc.count());
  }
 }
}

Path problem

Single source path problem

import java.util.ArrayList;
import java.util.Collections;

public class SingleSourcePath {

    private Graph G;
    private int s;

    private int[] pre;

    public SingleSourcePath(Graph G, int s){

        this.G = G;
        this.s = s;
        pre = new int[G.V()];
        for(int i = 0; i < pre.length; i + + )
            pre[i] = -1;

        dfs(s, s);
    }

    private void dfs(int v, int parent){

        pre[v] = parent;
        for(int w: G.adj(v))
            if(pre[w] == -1)
                dfs(w, v);
    }

    public boolean isConnectedTo(int t){
        G.validateVertex(t);
        return pre[t] != -1;
    }

    public Iterable<Integer> path(int t){

        ArrayList<Integer> res = new ArrayList<Integer>();
        if(!isConnectedTo(t)) return res;

        int cur = t;
        while(cur != s){
            res.add(cur);
            cur = pre[cur];
        }
        res.add(s);

        Collections.reverse(res);
        return res;
    }

    public static void main(String[] args){

        Graph g = new Graph("g.txt");
        SingleSourcePath sspath = new SingleSourcePath(g, 0);
        System.out.println("0 -> 6 : " + sspath.path(6));
        System.out.println("0 -> 5 : " + sspath.path(5));
    }
}

Path problem from one vertex to another vertex

import java.util.ArrayList;
import java.util.Collections;

public class Path {

    private Graph G;
    private int s, t;

    private int[] pre;
    private boolean[] visited;

    public Path(Graph G, int s, int t){

        G.validateVertex(s);
        G.validateVertex(t);

        this.G = G;
        this.s = s;
        this.t = t;

        visited = new boolean[G.V()];
        pre = new int[G.V()];
        for(int i = 0; i < pre.length; i + + )
            pre[i] = -1;

        dfs(s, s);
        for(boolean e: visited)
            System.out.print(e + " ");
        System.out.println();
    }

    private boolean dfs(int v, int parent){

        visited[v] = true;
        pre[v] = parent;

        if(v == t) return true;

        for(int w: G.adj(v))
            if(!visited[w])
                if(dfs(w, v))
                    return true;
        return false;
    }

    public boolean isConnected(){
        return visited[t];
    }

    public Iterable<Integer> path(){

        ArrayList<Integer> res = new ArrayList<Integer>();
        if(!isConnected()) return res;

        int cur = t;
        while(cur != s){
            res.add(cur);
            cur = pre[cur];
        }
        res.add(s);

        Collections.reverse(res);
        return res;
    }

    public static void main(String[] args){

        Graph g = new Graph("g.txt");
        Path path = new Path(g, 0, 6);
        System.out.println("0 -> 6 : " + path.path());

        Path path2 = new Path(g, 0, 5);
        System.out.println("0 -> 5 : " + path2.path());

        Path path3 = new Path(g, 0, 1);
        System.out.println("0 -> 1 : " + path3.path());
    }
}

Detect cycles in undirected graphs

Idea: Find a node that has been visited, and this node is not the previous node of the current node.

public class CycleDetection {

    private Graph G;
    private boolean[] visited;
    private boolean hasCycle = false;

    public CycleDetection(Graph G){

        this.G = G;
        visited = new boolean[G.V()];
        for(int v = 0; v < G.V(); v + + )
            if(!visited[v])
                if(dfs(v, v)){
                    hasCycle = true;
                    break;
                }
    }

    // Starting from vertex v, determine whether there is a cycle in the graph
    private boolean dfs(int v, int parent){

        visited[v] = true;
        for(int w: G.adj(v))
            if(!visited[w]){
                if(dfs(w, v)) return true;
            }
            else if(w != parent)
                return true;
        return false;
    }

    public boolean hasCycle(){
        return hasCycle;
    }

    public static void main(String[] args){

        Graph g = new Graph("g.txt");
        CycleDetection cycleDetection = new CycleDetection(g);
        System.out.println(cycleDetection.hasCycle());

        Graph g2 = new Graph("g2.txt");
        CycleDetection cycleDetection2 = new CycleDetection(g2);
        System.out.println(cycleDetection2.hasCycle());
    }
}

Detection of bipartite graph

Idea: Start dyeing one by one from a certain point.

import java.util.ArrayList;

public class BipartitionDetection {

    private Graph G;

    private boolean[] visited;
    private int[] colors;
    private boolean isBipartite = true;

    public BipartitionDetection(Graph G){

        this.G = G;
        visited = new boolean[G.V()];
        colors = new int[G.V()];
        for(int i = 0; i < G.V(); i + + )
            colors[i] = -1;

        for(int v = 0; v < G.V(); v + + )
            if(!visited[v])
                if(!dfs(v, 0)){
                    isBipartite = false;
                    break;
                }
    }

    private boolean dfs(int v, int color){

        visited[v] = true;
        colors[v] = color;
        for(int w: G.adj(v))
            if(!visited[w]){
                if(!dfs(w, 1 - color)) return false;
            }
            else if(colors[w] == colors[v])
                return false;
        return true;
    }

    public boolean isBipartite(){
        return isBipartite;
    }

    public static void main(String[] args){

        Graph g = new Graph("g.txt");
        BipartitionDetection bipartitionDetection = new BipartitionDetection(g);
        System.out.println(bipartitionDetection.isBipartite);
        // true

        Graph g2 = new Graph("g2.txt");
        BipartitionDetection bipartitionDetection2 = new BipartitionDetection(g2);
        System.out.println(bipartitionDetection2.isBipartite);
        // false

        Graph g3 = new Graph("g3.txt");
        BipartitionDetection bipartitionDetection3 = new BipartitionDetection(g3);
        System.out.println(bipartitionDetection3.isBipartite);
        // true
    }
}