結果
| 問題 |
No.1479 Matrix Eraser
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-06-17 13:37:55 |
| 言語 | TypeScript (5.7.2) |
| 結果 |
AC
|
| 実行時間 | 1,471 ms / 3,000 ms |
| コード長 | 5,356 bytes |
| コンパイル時間 | 8,408 ms |
| コンパイル使用メモリ | 232,800 KB |
| 実行使用メモリ | 144,488 KB |
| 最終ジャッジ日時 | 2024-12-31 16:39:54 |
| 合計ジャッジ時間 | 48,310 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 39 |
ソースコード
import * as fs from 'fs'
// import * as readline from 'readline'
// const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
// const ask = (query: string) => new Promise<string>((resolve) => rl.question(query, resolve))
// // Don't forget `rl.close()`.
const INT = Math.floor
declare global {
interface Array<T> {
last(): T | undefined
isEmpty(): boolean
}
}
Array.prototype.last = function () {
return this.length === 0 ? undefined : this[this.length - 1]
}
Array.prototype.isEmpty = function () {
return this.length === 0
}
const less = <T>(a: T, b: T) => (a == b ? 0 : a < b ? -1 : 1)
const greater = <T>(a: T, b: T) => (a == b ? 0 : a < b ? 1 : -1)
const bigIntMax = (...args: bigint[]) => args.reduce((m, e) => (e > m ? e : m))
const bigIntMin = (...args: bigint[]) => args.reduce((m, e) => (e < m ? e : m))
const bigIntAbs = (arg: bigint) => (arg < 0 ? -arg : arg)
declare const stdin: number
function read_stdin() {
return fs.readFileSync(process.env.NODE_ENV === 'debug' ? stdin : process.stdin.fd, 'utf8')
}
class Input {
readonly inputs: string[]
private index = 0
constructor(str?: string) {
this.inputs = (str ? str : read_stdin()).split(/\s+/)
}
number() {
return Number(this.inputs[this.index++])
}
numbers(n: number) {
return this.inputs.slice(this.index, (this.index += n)).map(Number)
}
bigint() {
return BigInt(this.inputs[this.index++])
}
bigints(n: number) {
return this.inputs.slice(this.index, (this.index += n)).map(BigInt)
}
word() {
return this.inputs[this.index++]
}
words(n: number) {
return this.inputs.slice(this.index, (this.index += n))
}
}
function array<T>(len: number, init: T): T[] {
return Array(len).fill(init)
}
function array2<T>(h: number, w: number, init: T): T[][] {
return array(h, 0).map(() => array(w, init))
}
type Edge = { to: number; cap: number; rev: Edge }
class Dinic {
private level: number[]
private edges: Edge[][]
private edges2: Edge[][]
constructor(private V: number) {
this.level = Array(V)
this.edges = [...Array(V)].map(() => [])
this.edges2 = [...Array(V)].map(() => [])
}
getEdges(from: number) {
return this.edges2[from]
}
addEdge(from: number, to: number, cap: number) {
const e: Edge = { to, cap } as any
const rev_e = { to: from, cap: 0, rev: e }
e.rev = rev_e
this.edges[from].push(e)
this.edges[to].push(rev_e)
this.edges2[from].push(e)
}
private bfs(s: number) {
this.level.fill(-1)
let q = [s]
this.level[s] = 0
let level = 1
while (!q.isEmpty()) {
const qq: number[] = []
while (!q.isEmpty()) {
const v = q.pop()!
for (const e of this.edges[v]) {
if (e.cap > 0 && this.level[e.to] < 0) {
this.level[e.to] = level
qq.push(e.to)
}
}
}
q = qq
level++
}
}
private dfs(s: number, t: number) {
const iter: number[] = Array(this.V).fill(0)
type Info = { v: number; f: number; rf: number; parent?: Info; edge?: Edge }
const stack: Info[] = [{ v: s, f: Infinity, rf: 0 }]
while (!stack.isEmpty()) {
const top = stack.last()!
if (top.v === t) {
stack.pop()
top.parent!.rf += top.f
top.edge!.cap -= top.f
top.edge!.rev.cap += top.f
continue
}
let hasEdge = false
const f = top.f - top.rf
if (f > 0) {
for (let i = iter[top.v]; i < this.edges[top.v].length; i++) {
iter[top.v] = i + 1
const e = this.edges[top.v][i]
if (e.cap > 0 && this.level[top.v] < this.level[e.to]) {
hasEdge = true
stack.push({ v: e.to, f: Math.min(f, e.cap), rf: 0, parent: top, edge: e })
break
}
}
}
if (!hasEdge) {
if (top.v === s) return top.rf
stack.pop()
if (top.rf > 0) {
top.parent!.rf += top.rf
top.edge!.cap -= top.rf
top.edge!.rev.cap += top.rf
}
}
}
return 0
}
maxFlow(s: number, t: number) {
let flow = 0
while (true) {
this.bfs(s)
if (this.level[t] < 0) return flow
flow += this.dfs(s, t)
}
}
}
function main() {
const input = new Input()
const H = input.number()
const W = input.number()
const A: { i: number; j: number }[][] = [...Array(5e5 + 1)].map(() => [])
for (let i = 0; i < H; i++) {
for (let j = 0; j < W; j++) {
const a = input.number()
A[a].push({ i, j })
}
}
let ans = 0
const r_map = array(H, 0)
const c_map = array(W, 0)
for (let a = 1; a <= 5e5; a++) {
if (A[a].isEmpty()) continue
const r_set = new Set<number>()
const c_set = new Set<number>()
for (const { i, j } of A[a]) {
r_set.add(i)
c_set.add(j)
}
const R = r_set.size
const C = c_set.size
const s = 0
const t = 1
const g = new Dinic(R + C + 2)
Array.from(r_set).forEach((r, idx) => {
r_map[r] = idx
g.addEdge(s, 2 + idx, 1)
})
Array.from(c_set).forEach((c, idx) => {
c_map[c] = idx
g.addEdge(2 + R + idx, t, 1)
})
for (const { i, j } of A[a]) {
g.addEdge(2 + r_map[i], 2 + R + c_map[j], 1)
}
const f = g.maxFlow(s, t)
ans += f
}
console.log(ans)
}
main()