結果
| 問題 | No.1479 Matrix Eraser |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-04-29 10:15:46 |
| 言語 | Java (openjdk 23) |
| 結果 |
AC
|
| 実行時間 | 2,459 ms / 3,000 ms |
| コード長 | 2,755 bytes |
| 記録 | |
| コンパイル時間 | 3,839 ms |
| コンパイル使用メモリ | 81,820 KB |
| 実行使用メモリ | 265,124 KB |
| 最終ジャッジ日時 | 2024-07-08 09:29:57 |
| 合計ジャッジ時間 | 55,523 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 39 |
ソースコード
package yukicoder;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class No1479_2 {
private static class Values {
public HashMap<Integer, Integer> di, dj;
public List<Integer[]> ij;
public Values() {
di = new HashMap<Integer, Integer> ();
dj = new HashMap<Integer, Integer> ();
ij = new ArrayList<Integer[]>();
}
}
private static int V;
private static int[] match;
private static boolean[] used;
private static List<List<Integer>> G;
private static void add_edge(int u, int v) {
G.get(u).add(v);
G.get(v).add(u);
}
private static boolean dfs(int v) {
used[v] = true;
for (int u : G.get(v)) {
int w = match[u];
if (w < 0 || !used[w] && dfs(w)) {
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
private static int bipartite_matching() {
int res = 0;
match = new int[V];
Arrays.fill(match, -1);
for (int v=0; v < V; v++) {
if (match[v] < 0) {
used = new boolean[V];
if (dfs(v)) {
res++;
}
}
}
return res;
}
private static int mpc(int h, int w) {
int res = bipartite_matching();
List<Integer> matched = new ArrayList<Integer>();
for (int i=h; i < h+w; i++) {
matched.add(match[i]);
}
int left = h, right = 0;
for (int v = 0; v < h; v++) {
if (!matched.contains(v)) {
left--;
for (int u : G.get(v)) {
right++;
if (match[u] >= 0) {
left--;
}
}
}
}
return left + right;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int H = scan.nextInt();
int W = scan.nextInt();
HashMap<Integer, Values> S = new HashMap<Integer, Values>();
for (int i=0; i < H; i++) {
for (int j=0; j < W; j++) {
int a = scan.nextInt();
if (a > 0) {
if (!S.containsKey(a)) {
Values v = new Values();
v.di.put(i, 0);
v.dj.put(j, 0);
v.ij.add(new Integer[] {0, 0});
S.put(a, v);
} else {
Values v = S.get(a);
int ai, aj;
if (v.di.containsKey(i)) {
ai = v.di.get(i);
} else {
ai = v.di.size();
v.di.put(i, ai);
}
if (v.dj.containsKey(j)) {
aj = v.dj.get(j);
} else {
aj = v.dj.size();
v.dj.put(j, aj);
}
v.ij.add(new Integer[] {ai, aj});
}
}
}
}
scan.close();
int cnt = 0;
for (Values v : S.values()) {
int h = v.di.size();
int w = v.dj.size();
V = h + w;
G = new ArrayList<List<Integer>>();
for (int i=0; i < V; i++) {
G.add(new ArrayList<Integer>());
}
for (Integer[] i : v.ij) {
add_edge(i[0], i[1]+h);
}
int n = mpc(h, w);
cnt += n;
}
System.out.println(cnt);
}
}