結果

問題 No.421 しろくろチョコレート
ユーザー rpy3cpprpy3cpp
提出日時 2016-09-09 23:34:21
言語 Python3
(3.12.2 + numpy 1.26.4 + scipy 1.12.0)
結果
AC  
実行時間 937 ms / 2,000 ms
コード長 3,220 bytes
コンパイル時間 109 ms
コンパイル使用メモリ 12,104 KB
実行使用メモリ 12,044 KB
最終ジャッジ日時 2023-10-24 14:47:24
合計ジャッジ時間 6,587 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 31 ms
10,420 KB
testcase_01 AC 95 ms
11,096 KB
testcase_02 AC 45 ms
10,600 KB
testcase_03 AC 33 ms
10,460 KB
testcase_04 AC 36 ms
10,556 KB
testcase_05 AC 39 ms
10,588 KB
testcase_06 AC 32 ms
10,468 KB
testcase_07 AC 61 ms
10,832 KB
testcase_08 AC 41 ms
10,600 KB
testcase_09 AC 35 ms
10,500 KB
testcase_10 AC 35 ms
10,496 KB
testcase_11 AC 57 ms
10,856 KB
testcase_12 AC 31 ms
10,412 KB
testcase_13 AC 32 ms
10,412 KB
testcase_14 AC 31 ms
10,412 KB
testcase_15 AC 31 ms
10,412 KB
testcase_16 AC 120 ms
11,512 KB
testcase_17 AC 162 ms
11,536 KB
testcase_18 AC 190 ms
11,556 KB
testcase_19 AC 30 ms
10,412 KB
testcase_20 AC 91 ms
11,192 KB
testcase_21 AC 118 ms
11,364 KB
testcase_22 AC 56 ms
10,876 KB
testcase_23 AC 31 ms
10,412 KB
testcase_24 AC 30 ms
10,412 KB
testcase_25 AC 30 ms
10,412 KB
testcase_26 AC 31 ms
10,412 KB
testcase_27 AC 31 ms
10,412 KB
testcase_28 AC 44 ms
11,008 KB
testcase_29 AC 50 ms
11,204 KB
testcase_30 AC 54 ms
11,028 KB
testcase_31 AC 83 ms
12,044 KB
testcase_32 AC 53 ms
11,120 KB
testcase_33 AC 66 ms
11,124 KB
testcase_34 AC 34 ms
10,492 KB
testcase_35 AC 34 ms
10,504 KB
testcase_36 AC 67 ms
10,864 KB
testcase_37 AC 142 ms
11,516 KB
testcase_38 AC 187 ms
11,752 KB
testcase_39 AC 49 ms
10,760 KB
testcase_40 AC 74 ms
11,084 KB
testcase_41 AC 38 ms
10,600 KB
testcase_42 AC 37 ms
10,532 KB
testcase_43 AC 52 ms
10,804 KB
testcase_44 AC 101 ms
11,316 KB
testcase_45 AC 38 ms
10,572 KB
testcase_46 AC 41 ms
10,580 KB
testcase_47 AC 87 ms
11,004 KB
testcase_48 AC 937 ms
11,776 KB
testcase_49 AC 50 ms
10,692 KB
testcase_50 AC 40 ms
10,616 KB
testcase_51 AC 108 ms
11,408 KB
testcase_52 AC 61 ms
10,828 KB
testcase_53 AC 34 ms
10,508 KB
testcase_54 AC 42 ms
10,616 KB
testcase_55 AC 34 ms
10,508 KB
testcase_56 AC 34 ms
10,508 KB
testcase_57 AC 39 ms
10,584 KB
testcase_58 AC 88 ms
11,076 KB
testcase_59 AC 42 ms
10,664 KB
testcase_60 AC 242 ms
11,864 KB
testcase_61 AC 157 ms
11,892 KB
testcase_62 AC 30 ms
10,416 KB
testcase_63 AC 31 ms
10,416 KB
testcase_64 AC 30 ms
10,412 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

def bp_match(Ss, Ts, Es):
    '''2部グラフのマッチング問題をとく。
    '''
    super_source = len(Ss) + len(Ts)
    super_target = super_source + 1
    Cs = [dict() for i in range(super_target + 1)]
    for si, ti in Es:
        Cs[si][ti] = 1
        Cs[ti][si] = 0
    for si in Ss:
        Cs[super_source][si] = 1
        Cs[si][super_source] = 0
    for ti in Ts:
        Cs[super_target][ti] = 0
        Cs[ti][super_target] = 1
    return dinic(Cs, super_target + 1, super_source, super_target)

def dinic(cf, nV, s, t):
    dist = get_distance(cf, s, t)
    while dist[t] > 0:
        df = dfs(dist, cf, s, t, float('inf'))
        while df:
            df = dfs(dist, cf, s, t, float('inf'))
        dist = get_distance(cf, s, t)
    return sum(cf[t].values())

def get_distance(cf, s, t):
    dist = [-1] * len(cf)
    dist[s] = 0
    frontiers = [s]
    while frontiers:
        new_frontiers = []
        for u in frontiers:
            for v, capacity in cf[u].items():
                if dist[v] == -1 and capacity > 0:
                    dist[v] = dist[u] + 1
                    new_frontiers.append(v)
        frontiers = new_frontiers
    return dist

def dfs(dist, cf, u, t, df):
    if u == t:
        return df
    for v, capacity in cf[u].items():
        if dist[v] > dist[u] and capacity > 0:
            new_df = dfs(dist, cf, v, t, min(df, capacity))
            if new_df > 0:
                cf[u][v] -= new_df
                cf[v][u] += new_df
                return new_df
    return 0


def read_data():
    N, M = map(int, input().split())
    Ws = []
    Bs = []
    Es = []
    for i in range(N):
        Si = input()
        for j, s in enumerate(Si):
            if s == '.':
                continue
            elif s == 'w':
                Ws.append(i * M + j)
            elif s == 'b':
                Bs.append(i * M + j)
    Bset = set(Bs)
    for w in Ws:
        i, j = divmod(w, M)
        if i > 0 and w - M in Bset:
            Es.append((w, w - M))
        if w + M in Bset:
            Es.append((w, w + M))
        if j > 0 and w - 1 in Bset:
            Es.append((w, w - 1))
        if j < M - 1 and w + 1 in Bset:
            Es.append((w, w + 1))
    return N, M, Ws, Bs, Es

def renumber(Ws, Bs, Es):
    W_old2new = dict()
    B_old2new = dict()
    for i, w in enumerate(Ws):
        W_old2new[w] = i
    for i, b in enumerate(Bs, len(Ws)):
        B_old2new[b] = i
    newEs = []
    for w, b in Es:
        newEs.append((W_old2new[w], B_old2new[b]))
    newWs = list(range(len(Ws)))
    newBs = list(range(len(Ws), len(Ws) + len(Bs)))
    return newWs, newBs, newEs

def solve(N, M, Ws, Bs, Es):
    '''
    貪欲に、並んでwbのペアをとれるだけ取る。-> 二部マッチングで求める。
    残りのバラバラのをペアにする。
    w のみ or b のみを食べる。
    '''
    Ws, Bs, Es = renumber(Ws, Bs, Es)
    nw = len(Ws)
    nb = len(Bs)
    connected_pair = bp_match(Ws, Bs, Es)
    unconnected_pair = min(nw, nb) - connected_pair
    single = nw + nb - min(nw, nb) * 2
    return 100 * connected_pair + 10 * unconnected_pair + 1 * single

N, M, Ws, Bs, Es = read_data()
print(solve(N, M, Ws, Bs, Es))
0