UVa Online Judge Challenge "11045"

This is a maximum flow problem on a bipartite graph. I created the flow chart above to visualize the 3 test cases. The virtual judge run time was 0.18s.

Problem

Solution

  1/* * * * * * * *
  2Tristan Madden
  32018-05-01
  4https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1986
  5* * * * * * * * */
  6
  7import java.io.BufferedReader;
  8import java.io.IOException;
  9import java.io.InputStreamReader;
 10import java.util.Arrays;
 11import java.util.HashMap;
 12import java.util.LinkedList;
 13import java.util.Queue;
 14public class Main {
 15    static int source = 0;
 16    static int sink = 1;
 17    static HashMap<String, Integer> map = new HashMap<>(6);
 18    public static void main(String[] args) throws IOException {
 19        map.put("XS", 2);
 20        map.put("S", 3);
 21        map.put("M", 4);
 22        map.put("L", 5);
 23        map.put("XL", 6);
 24        map.put("XXL", 7);
 25        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 26        int testCases = Integer.parseInt(br.readLine());
 27        while (testCases-- > 0) {
 28            String[] nm = br.readLine().split(" ");
 29            //N is multiple of 6, 1 ≤ N ≤ 36
 30            int N = Integer.parseInt(nm[0]);
 31            //M, 1 ≤ M ≤ 30, indicates the number of volunteers, with N ≥ M
 32            int M = Integer.parseInt(nm[1]);
 33            /* * * * * * * * * * * * * * * * * * * * *
 34            |* The size of the graph will be the sum of: 
 35            |* -the number of shirt sizes available (6)
 36            |* -the number of volunteers (M)
 37            |* -the sink and source (2)
 38            |* * * * * * * * * * * * * * * * * * * * */
 39            MyGraph graph = new MyGraph(M + 8);
 40            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 41            |* S T E P   O N E
 42            |* Construct the edges from the source node to the t-shirt nodes.
 43            |* The capacity of these edges will be N/6, or the number of t-shirts
 44            |* in stock of this size.
 45            |* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 46            int t;
 47            for (t = 0; t < 6; t++) {
 48                graph.addEdge(source, t + 2, N / 6);
 49            }
 50            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 51            |* S T E P   T W O
 52            |* Construct the edges from the t-shirt nodes to the volunteer nodes.
 53            |* This is the bipartite graph.
 54            |* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 55            int i, a, b;
 56            for (i = 0; i < M; i++) {
 57                String[] sizes = br.readLine().split(" ");
 58                a = map.get(sizes[0]);
 59                b = map.get(sizes[1]);
 60                graph.addEdge(a, i + 8, 1);
 61                graph.addEdge(b, i + 8, 1);
 62            }
 63            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 64            |* S T E P   T H R E E
 65            |* Construct the edges from the volunteer nodes to the sink node.
 66            |* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 67            int v;
 68            for (v = 0; v < M; v++) {
 69                graph.addEdge(v + 8, sink, 1);
 70            }
 71            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 72            |* S T E P   F O U R
 73            |* Run Max Flow on the bipartite graph.
 74            |* If the maximum flow is equal to the number of volunteers, print
 75            |* "YES". Otherwise, print "NO".
 76            |* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 77            if (graph.maxFlow(source, sink) == M) {
 78                System.out.println("YES");
 79            } else {
 80                System.out.println("NO");
 81            }
 82        }
 83    }
 84}
 85class MyGraph {
 86    int size;
 87    int[][] edges;
 88    MyGraph(int _size) {
 89        this.size = _size;
 90        this.edges = new int[size][size];
 91    }
 92    void addEdge(int x, int y, int weight) {
 93        edges[x][y] += weight;
 94    }
 95    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 96    |* M A X   F L O W
 97    |* This is a franken-method pieced together from other solution I found 
 98    |* online. Pretty much treating it as a black box. 
 99    |* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
100    int maxFlow(int source, int sink) {
101        int[] prev = new int[size];
102        int answer = 0;
103        int mincut = Integer.MAX_VALUE; //infinity
104        while (true) {
105            Queue<Integer> q = new LinkedList<>();
106            q.add(source);
107            Arrays.fill(prev, -1);
108            while (!q.isEmpty() && prev[sink] == -1) {
109                int u = q.remove();
110                for (int v = 0; v < size; v++) {
111                    if (v != source && prev[v] == -1 && edges[u][v] > 0) {
112                        q.add(v);
113                        prev[v] = u;
114                    }
115                }
116            }
117            if (prev[sink] == -1) {
118                break;
119            }
120            int y = sink;
121            int x = prev[y];
122            while (x != -1) {
123                mincut = Math.min(mincut, edges[x][y]);
124                y = x;
125                x = prev[y];
126            }
127            int v = sink;
128            int u = prev[v];
129            while (u != -1) {
130                edges[u][v] -= mincut;
131                edges[v][u] += mincut;
132                v = u;
133                u = prev[v];
134            }
135            answer += mincut;
136        }
137        return answer;
138    }
139}