結果

問題 No.421 しろくろチョコレート
ユーザー rpy3cpprpy3cpp
提出日時 2016-09-09 23:34:50
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 508 ms / 2,000 ms
コード長 3,220 bytes
コンパイル時間 154 ms
コンパイル使用メモリ 81,760 KB
実行使用メモリ 83,656 KB
最終ジャッジ日時 2023-10-24 14:47:38
合計ジャッジ時間 8,750 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 38 ms
53,544 KB
testcase_01 AC 137 ms
77,100 KB
testcase_02 AC 79 ms
75,940 KB
testcase_03 AC 58 ms
68,224 KB
testcase_04 AC 72 ms
75,700 KB
testcase_05 AC 77 ms
75,736 KB
testcase_06 AC 46 ms
64,204 KB
testcase_07 AC 130 ms
76,916 KB
testcase_08 AC 75 ms
75,744 KB
testcase_09 AC 65 ms
72,496 KB
testcase_10 AC 69 ms
73,752 KB
testcase_11 AC 117 ms
76,804 KB
testcase_12 AC 36 ms
53,544 KB
testcase_13 AC 35 ms
53,544 KB
testcase_14 AC 35 ms
53,544 KB
testcase_15 AC 34 ms
53,544 KB
testcase_16 AC 175 ms
78,156 KB
testcase_17 AC 232 ms
79,072 KB
testcase_18 AC 241 ms
78,636 KB
testcase_19 AC 36 ms
53,544 KB
testcase_20 AC 162 ms
78,056 KB
testcase_21 AC 181 ms
77,608 KB
testcase_22 AC 118 ms
76,584 KB
testcase_23 AC 37 ms
53,544 KB
testcase_24 AC 35 ms
53,544 KB
testcase_25 AC 35 ms
53,544 KB
testcase_26 AC 34 ms
53,544 KB
testcase_27 AC 34 ms
53,544 KB
testcase_28 AC 77 ms
76,608 KB
testcase_29 AC 85 ms
76,872 KB
testcase_30 AC 114 ms
77,480 KB
testcase_31 AC 98 ms
77,540 KB
testcase_32 AC 104 ms
76,724 KB
testcase_33 AC 153 ms
78,024 KB
testcase_34 AC 56 ms
68,344 KB
testcase_35 AC 59 ms
70,412 KB
testcase_36 AC 127 ms
76,588 KB
testcase_37 AC 243 ms
79,028 KB
testcase_38 AC 291 ms
81,588 KB
testcase_39 AC 93 ms
76,208 KB
testcase_40 AC 151 ms
77,660 KB
testcase_41 AC 93 ms
76,280 KB
testcase_42 AC 75 ms
75,888 KB
testcase_43 AC 95 ms
76,440 KB
testcase_44 AC 186 ms
78,232 KB
testcase_45 AC 72 ms
75,832 KB
testcase_46 AC 87 ms
76,092 KB
testcase_47 AC 147 ms
77,600 KB
testcase_48 AC 508 ms
83,656 KB
testcase_49 AC 95 ms
76,588 KB
testcase_50 AC 84 ms
75,776 KB
testcase_51 AC 211 ms
78,872 KB
testcase_52 AC 133 ms
77,256 KB
testcase_53 AC 67 ms
73,300 KB
testcase_54 AC 76 ms
76,028 KB
testcase_55 AC 66 ms
72,832 KB
testcase_56 AC 68 ms
73,540 KB
testcase_57 AC 84 ms
75,956 KB
testcase_58 AC 149 ms
77,372 KB
testcase_59 AC 77 ms
75,864 KB
testcase_60 AC 354 ms
80,908 KB
testcase_61 AC 254 ms
79,496 KB
testcase_62 AC 36 ms
53,544 KB
testcase_63 AC 34 ms
53,544 KB
testcase_64 AC 37 ms
59,240 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