Problem:
Cycle Detection for a Directed Graph

Find a cycle in a directed graph G(V, E).

Input

A directed graph G is given in the following format:

|V| |E|
s0 t0
s1 t1
:
s|E|-1 t|E|-1

|V| is the number of nodes and |E| is the number of edges in the graph. The graph nodes are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target nodes of i-th edge (directed).

Output

Print 1 if G has cycle(s), 0 otherwise.

Constraints

1 ≤ |V| ≤ 100

0 ≤ |E| ≤ 1,000

si ≠ ti

Sample Input 1

3 3
0 1
0 2
1 2

Sample Output 1

0

Sample Input 2

3 3
0 1
1 2
2 0

Sample Output 2

1

Solution in JAVA (judge verdict: Accepted)


import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.TreeSet;

public class Main {

    public static class TopologicalSort_Kahn {

        boolean hasCycle;
        LinkedList<Integer> sortedOrder;

        public TopologicalSort_Kahn(WeightedDigraph graph) {
            sortedOrder = new LinkedList<Integer>();
            TreeSet<Integer> zeroInVerts = new TreeSet<Integer>();
            int[] inEdge = new int[graph.numVertex];
            for (List<WeightedDigraph.Edge> edges : graph.srcEdges) {
                for (WeightedDigraph.Edge edge : edges) {
                    inEdge[edge.targetVertex]++;
                }
            }
            for (int v = 0; v < graph.numVertex; v++) {
                if (inEdge[v] == 0) {
                    zeroInVerts.add(v);
                }
            }

            while (!zeroInVerts.isEmpty()) {
                int vert = zeroInVerts.pollFirst();
                sortedOrder.add(vert);
                List<WeightedDigraph.Edge> edges = graph.srcEdges[vert];
                for (WeightedDigraph.Edge edge : edges) {
                    inEdge[edge.targetVertex]--;
                    if (inEdge[edge.targetVertex] == 0) {
                        zeroInVerts.add(edge.targetVertex);
                    }
                }
            }

            for (int v = 0; v < graph.numVertex; v++) {
                if (inEdge[v] != 0) {
                    sortedOrder.clear();
                    hasCycle = true;
                    return;
                }
            }

        }

        public boolean hasCycle() {
            return hasCycle;
        }

        public Iterator<Integer> sortedOrder() {
            return sortedOrder.iterator();
        }
    }

    public static class WeightedDigraph {

        int numVertex;
        int numEdge;

        List<Edge>[] srcEdges;

        @SuppressWarnings("unchecked")
        public WeightedDigraph(int numV, int numE) {
            this.numVertex = numV;
            this.numEdge = numE;
            srcEdges = new List[numV];

            for (int i = 0; i < numV; i++) {
                srcEdges[i] = new ArrayList<Edge>();
            }
        }

        public void addEdge(int srcVertex, int targetVertex, int weight) {
            Edge e = new WeightedDigraph.Edge(srcVertex, targetVertex, weight);
            srcEdges[srcVertex].add(e);
        }

        public static class Edge {

            int srcVertex;
            int targetVertex;
            int weight;

            public Edge(int srcVertex, int targetVertex, int weight) {
                this.srcVertex = srcVertex;
                this.targetVertex = targetVertex;
                this.weight = weight;
            }
        }

    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int v = in.nextInt();
        int e = in.nextInt();
        WeightedDigraph graph = new WeightedDigraph(v, e);
        while (e-- > 0) {
            graph.addEdge(in.nextInt(), in.nextInt(), 1);
        }
        TopologicalSort_Kahn topSort = new TopologicalSort_Kahn(graph);
        System.out.println(topSort.hasCycle() ? 1 : 0);
    }
}