private static ArrayList<ResidualEdge> minCostFlowWithBellmanFordSub(
            ArrayList<ResidualEdge>[] edges, int s, int t) {
        int n = edges.length;
        ResidualEdge[] prevE = new ResidualEdge[n];
        int[] prevV = new int[n];
        int[] dist = new int[n];
        Arrays.fill(prevV, -1);
        Arrays.fill(dist, INF);
        dist[s] = 0;
        prevV[s] = -2;  // make sure source is not rediscovered
        for (int i = 0; i < n; i++) {
            for (int v = 0; v < n; v++) {
                for (ResidualEdge e : edges[v]) {
                    if (e.residual > 0 && dist[e.to] > dist[v] + e.cost) {
                        dist[e.to] = dist[v] + e.cost;
                        prevE[e.to] = e;
                        prevV[e.to] = v;
                    }
                }
            }
        }
        if (prevE[t] == null) return null;
        ArrayList<ResidualEdge> path = new ArrayList<ResidualEdge>();
        ResidualEdge e;
        for (int v = t;; v = prevV[v]) {
            e = prevE[v];
            if (e == null) break;
            path.add(e);
        }
        return path;
    }