0

In my task I try to use Kuhn-algorithm to find solution for maximum matchings in bipartite graphs.

Description of the problem:

Floor in a room the size of M × N paved with parquet. However, some tile flooring were broken. Peter decided to redecorate the room by replacing the damaged cells. He found that the parquet tiles come in two types - the size of 1 × 2, which cost A coins (a little thought, Peter realized that the 1 × 2 tiles can be rotated 90 degrees, thereby producing tiles 2 × 1) and size 1 × 1, which are B coins. Peter cannot divide double tiles by two.

Find the minimum cost to repair floor.

Specifications: Input: The first line contains the four numbers: N, M, A, B ( 1 ≤ N, M ≤ 300 , A, B - integers modulo not exceeding 1000). Each of the next N lines contains M characters: "." (dot) represents unspoiled tile flooring, and the symbol "*" (asterisk) - damaged. At the end of the rows can go insignificant spaces. At the end of the file may be empty strings.

Output: a single number - the minimum amount of money to repair.

For first input line 300 300 1000 1000 and next 300 equal lines with 300 asterisk characters I get Exception in thread "main" java.lang.StackOverflowError at java.util.ArrayList.iterator when recursive calls 1024 times.

Code:

import java.io.*;
import java.util.*;

public class BrokenParquet {
    static boolean findPath(List<Integer>[] g, int u1, int[] matching, boolean[] vis) {
        if (vis[u1]) return false;
        vis[u1] = true;
        for (int v : g[u1]) {
            int u2 = matching[v];
            if (u2 == -1 || !vis[u2] && findPath(g, u2, matching, vis)) {
                matching[v] = u1;
                return true;
            }
        }
        return false;
    }

    public static int maxMatching(List<Integer>[] g, int n2) {
        int n1 = g.length;
        int[] matching = new int[n2];
        Arrays.fill(matching, -1);
        int matches = 0;
        for (int u = 0; u < n1; u++) {
            if (findPath(g, u, matching, new boolean[n1]))
                ++matches;
            /*if (matches>36300)
                System.out.println(matches);*/
        }
        return matches;
    }

    public static void main(String[] args) throws Exception {

        BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
        int n=0,m=0,a=0,b=0;

            String s = "";

        try {
            int c;

                StringBuilder sb = new StringBuilder();

                while ((c = rdr.read()) != '\n') {
                    sb.append((char) c);
                    s = sb.toString();
                    s.trim();
                }
        } catch (IOException e) {
            System.exit(0);
            e.printStackTrace();
        }

        if (s == null) System.exit(0);
            String[] num = s.split("[^\\p{Digit}*]");

        if (num.length != 4) System.exit(0);

        try {
             n = Integer.parseInt(num[0]);
             m = Integer.parseInt(num[1]);
             a = Integer.parseInt(num[2]);
             b = Integer.parseInt(num[3]);
        } catch(Exception e) {System.exit(0);}
        if (n<1 || m<1 || n>300 || m>300 || a>1000 || b>1000 || a<0 || b<0) System.exit(0);
        char[][] chars = new char[n][m];
        s = "";


                try {

                        int c;
                    for (int i = 0; i < chars.length; i++) {
                        StringBuilder sb = new StringBuilder();
                        int l = 0;
                        while ((c = rdr.read()) != -1) {
                        if ((char) c == '\n') break;
                        if (((char) c == '*' || (char) c == '.') && l<m) {
                            sb.append((char) c);
                            l++;
                        }
                    }
                        if (l < m) for (int j = 0; j < m-l; j++) sb.append('.');
                        s = sb.toString();



                        chars[i] = s.toCharArray();
                    }
                    rdr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (rdr != null) {
                        try {
                            rdr.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }

            rdr.close();
        int n1 = m*n;
        int n2 = n1;
        List<Integer>[] g = new List[n1];
        for (int i = 0; i < n1; i++) {
            g[i] = new ArrayList<Integer>();
        }
        int o = 0, w = 0;
        for (int i = 0; i < chars.length; i++) {
            for (int j = 0; j < chars[i].length; j++) {
                char c = chars[i][j];
                if (c == '*') {
                    w++;
                    if (j > 0 && chars[i][j-1] == '*') g[o].add(o-1);
                    if (j <= chars[i].length-2 && chars[i][j+1] == '*') g[o].add(o+1);
                    if (i > 0 && chars[i-1][j] == '*') g[o].add(o-m);
                    if (i <= chars.length-2 && chars[i+1][j] == '*') g[o].add(o+m);
                }
                o++;
            }
        }
        int d = maxMatching(g, n2)/2;
        if (2*b>a) System.out.print(d*a+(w-d*2)*b);
        else System.out.print(w * b);

        }
    }

I'm looking for an answer without increasing the Java stack size.

karel
  • 5,489
  • 46
  • 45
  • 50
Razor
  • 13
  • 6
  • You can try to turn `for (int v : g[u1])` into an index based loop which does not create an iterator but there is a limit to recursion. Maybe your algorithm / the input data is just more than your pc can handle. And to fix such a problem you would need to rewrite your algorithm. Prevent unnecessary steps, make it non-recursive, ... – zapl Dec 06 '13 at 18:08
  • The default stack size is quite low. Increase it or try to avoid recursion. – MrSmith42 Dec 06 '13 at 18:12
  • If the specification doesn't give you and upper bound the values of N and M, you should consider using java.util.Stack to hold the paths in the heap instead of doing recursion. – user845279 Dec 06 '13 at 20:20

0 Answers0