JAVA O(n^3) Kuhn-Munkres (Hungarian)
```\nclass Solution {\n    public int maxCompatibilitySum(int[][] students, int[][] mentors) {\n        return sln1(students, mentors);\n    }\n    \n    privat
```\nclass Solution {\n    public int maxCompatibilitySum(int[][] students, int[][] mentors) {\n        return sln1(students, mentors);\n    }\n    \n    private int sln1(int[][] sts, int[][] mts){\n        int m = sts.length;\n        int n = sts[0].length;\n        int[][] arr = new int[m][m];\n        for(int i = 0;i<m;i++){\n            for(int j = 0;j< m;j++){\n                int score = 0;\n                for(int k = 0;k < n;k++){\n                    score += 1^sts[i][k]^mts[j][k];\n                }\n                arr[i][j] = score;\n            }\n        }\n        \n        return km(arr);\n    }\n    \n    private int km(int[][] w){\n        int n = w.length;\n        int m = w[0].length;\n        int[] lx = new int[n];\n        int[] ly = new int[m];\n        int[] from = new int[m];\n        int[] to = new int[n];\n        \n        Arrays.fill(from, -1);\n        Arrays.fill(to, -1);\n        \n        for(int i=0;i<n;i++)//\u521D\u59CB\u5316\u6807\u6746 \n            for(int j=0;j<m;j++)\n                lx[i]=Math.max(lx[i],w[i][j]);\n        for(int i=0;i<n;i++) {//x\u8FB9\u6BCF\u4E2A\u70B9\u7684\u5339\u914D \n            while(true) {\n                boolean[] s = new boolean[n];\n                boolean[] t = new boolean[m];\n                if(find(i, s, t, from, to, lx, ly, w)) break;\n                else update(s, t, from, to, lx, ly, w);\n            }\n        }\n        \n        int ans=0;\n        for(int i=0;i<n;i++)//\u8BA1\u7B97\u7B54\u6848 \n            ans+=w[i][to[i]];\n        \n        return ans;\n    }\n    \n    private boolean find(int x, boolean[] s, boolean[] t, int[] from, int[] to, int[] lx, int[] ly, int[][] w) { //\u5308\u7259\u5229\u7B97\u6CD5 \n        int m = t.length;\n        s[x]=true;\n        for(int i=0;i<m;i++){\n            if(lx[x]+ly[i]==w[x][i]&&!t[i])  {\n                t[i]=true;\n                if(from[i]<0 || find(from[i], s, t, from, to, lx, ly, w)) {\n                    from[i]=x;\n                    to[x]=i;\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    \n    private void update(boolean[] s, boolean[] t, int[] from, int[] to, int[] lx, int[] ly, int[][] w)//\u66F4\u65B0\u6807\u6746 \n    {\n        int n = s.length;\n        int m = t.length;\n        int d = Integer.MAX_VALUE;\n        for(int i=0;i<n;i++){\n            if(s[i]){\n                for(int j=0;j<m;j++){\n                    if(!t[j]){\n                        d=Math.min(d,lx[i]+ly[j]-w[i][j]);//\u6309\u7167\u4E0A\u9762\u7ED9\u51FA\u7684\u539F\u5219\u8BA1\u7B97d \n                    }\n                }\n            }\n        }\n        for(int i=0;i<n;i++)//\u70B9\u96C6s\u4E2D\u7684\u70B9\u7684\u6807\u6746lx[i]-d \n            if(s[i]) lx[i]-=d;\n        for(int j=0;j<m;j++)//\u70B9\u96C6t\u4E2D\u7684\u70B9\u7684\u6807\u6746ly[j]+d \n            if(t[j]) ly[j]+=d;\n    }\n\n}
[]