172972025-06-19 18:19:4342Pontok és Négyzetekpypy3Accepted 100/100331ms72164 KiB
import sys
input = sys.stdin.readline

n, m = map(int, input().split())

dp = [[[[0 for _ in range(2)] for _ in range(2)] for _ in range(445)] for _ in range(445)]
rep_ = list(range(445))
siz_ = [1]*445
is_path = [False]*445
sides = [0]*445

def fint(v):
    if rep_[v] == v:
        return v
    rep_[v] = fint(rep_[v])
    return rep_[v]

def onion(a, b):
    a = fint(a)
    b = fint(b)
    if a == b:
        return
    siz_[b] += siz_[a]
    rep_[a] = b
    is_path[b] = is_path[b] or is_path[a]

for i in range(n * m):
    rep_[i] = i
    siz_[i] = 1

# vízszintes élek
for i in range(n + 1):
    line = input().strip()
    for j in range(m):
        z = line[j]
        if z == '1':
            if i != n:
                sides[i * m + j] += 1
            if i != 0:
                sides[(i - 1) * m + j] += 1
        else:
            if 0 < i < n:
                onion(i * m + j, (i - 1) * m + j)
            if i == 0:
                is_path[fint(i * m + j)] = True
            if i == n:
                is_path[fint((i - 1) * m + j)] = True

# függőleges élek
for i in range(n):
    line = input().strip()
    for j in range(m + 1):
        z = line[j]
        if z == '1':
            if j != m:
                sides[i * m + j] += 1
            if j != 0:
                sides[i * m + j - 1] += 1
        else:
            if 0 < j < m:
                onion(i * m + j, i * m + j - 1)
            if j == 0:
                is_path[fint(i * m + j)] = True
            if j == m:
                is_path[fint(i * m + j - 1)] = True

paths = []
cycles = []

for i in range(n * m):
    r = fint(i)
    if r == i and sides[i] != 4:
        if is_path[i]:
            paths.append(siz_[i])
        else:
            cycles.append(siz_[i])

paths.sort()
cycles.sort()

ps = len(paths)
cs = len(cycles)

for p in reversed(range(ps + 1)):
    for c in reversed(range(cs + 1)):
        if p == ps and c == cs:
            continue
        dp[p][c][0][0] = -int(1e5)
        dp[p][c][0][1] = -int(1e5)
        dp[p][c][1][0] = int(1e5)
        dp[p][c][1][1] = int(1e5)

        if p < ps:
            if p == ps - 1 and c == cs:
                dp[p][c][0][0] = paths[p]
            if p + 1 < ps:
                dp[p][c][0][0] = max(dp[p][c][0][0], dp[p + 1][c][1][0] + paths[p])
            if c < cs:
                dp[p][c][0][0] = max(dp[p][c][0][0], dp[p + 1][c][1][1] + paths[p])
            if paths[p] > 2:
                w2 = int(1e5)
                if p + 1 < ps:
                    w2 = min(w2, dp[p + 1][c][0][0])
                if c < cs:
                    w2 = min(w2, dp[p + 1][c][0][1])
                if w2 != int(1e5):
                    dp[p][c][0][0] = max(dp[p][c][0][0], w2 + paths[p] - 4)

            # 1 0
            if p == ps - 1 and c == cs:
                dp[p][c][1][0] = -paths[p]
            if p + 1 < ps:
                dp[p][c][1][0] = min(dp[p][c][1][0], dp[p + 1][c][0][0] - paths[p])
            if c < cs:
                dp[p][c][1][0] = min(dp[p][c][1][0], dp[p + 1][c][0][1] - paths[p])
            if paths[p] > 2:
                w2 = -int(1e5)
                if p + 1 < ps:
                    w2 = max(w2, dp[p + 1][c][1][0])
                if c < cs:
                    w2 = max(w2, dp[p + 1][c][1][1])
                if w2 != -int(1e5):
                    dp[p][c][1][0] = min(dp[p][c][1][0], w2 - paths[p] + 4)

        if c < cs:
            if c == cs - 1 and p == ps:
                dp[p][c][0][1] = cycles[c]
            if p < ps:
                dp[p][c][0][1] = max(dp[p][c][0][1], dp[p][c + 1][1][0] + cycles[c])
            if c + 1 < cs:
                dp[p][c][0][1] = max(dp[p][c][0][1], dp[p][c + 1][1][1] + cycles[c])
            w2 = int(2e5)
            if p < ps:
                w2 = min(w2, dp[p][c + 1][0][0])
            if c + 1 < cs:
                w2 = min(w2, dp[p][c + 1][0][1])
            if w2 != int(2e5):
                dp[p][c][0][1] = max(dp[p][c][0][1], w2 + cycles[c] - 8)

            if c == cs - 1 and p == ps:
                dp[p][c][1][1] = -cycles[c]
            if p < ps:
                dp[p][c][1][1] = min(dp[p][c][1][1], dp[p][c + 1][0][0] - cycles[c])
            if c + 1 < cs:
                dp[p][c][1][1] = min(dp[p][c][1][1], dp[p][c + 1][0][1] - cycles[c])
            w2 = -int(2e5)
            if p < ps:
                w2 = max(w2, dp[p][c + 1][1][0])
            if c + 1 < cs:
                w2 = max(w2, dp[p][c + 1][1][1])
            if w2 != -int(2e5):
                dp[p][c][1][1] = min(dp[p][c][1][1], w2 - cycles[c] + 8)

if ps == 0 and cs == 0:
    print(0)
else:
    res = max(dp[0][0][1][0] if ps != 0 else -int(2e5),
              dp[0][0][1][1] if cs != 0 else -int(2e5))
    print(res)
SubtaskSumTestVerdictTimeMemory
subtask120/20
1Accepted250ms70332 KiB
2Accepted248ms70244 KiB
3Accepted287ms70328 KiB
4Accepted284ms70340 KiB
5Accepted248ms70128 KiB
6Accepted246ms70332 KiB
7Accepted282ms70128 KiB
8Accepted280ms70292 KiB
9Accepted245ms70120 KiB
10Accepted245ms70120 KiB
11Accepted284ms70316 KiB
12Accepted282ms70416 KiB
subtask220/20
1Accepted246ms70184 KiB
2Accepted247ms70528 KiB
3Accepted282ms70304 KiB
4Accepted284ms70172 KiB
5Accepted257ms70304 KiB
6Accepted259ms70236 KiB
7Accepted272ms70348 KiB
8Accepted254ms70164 KiB
9Accepted250ms70328 KiB
10Accepted277ms70108 KiB
11Accepted270ms70336 KiB
12Accepted250ms70212 KiB
subtask320/20
1Accepted280ms70340 KiB
2Accepted246ms70120 KiB
3Accepted246ms70092 KiB
4Accepted282ms70156 KiB
5Accepted246ms70328 KiB
6Accepted246ms70304 KiB
7Accepted280ms70328 KiB
8Accepted280ms70320 KiB
9Accepted246ms70120 KiB
10Accepted246ms70120 KiB
11Accepted291ms70216 KiB
12Accepted282ms70224 KiB
13Accepted246ms70120 KiB
14Accepted245ms70116 KiB
15Accepted286ms70120 KiB
16Accepted280ms70340 KiB
17Accepted247ms70120 KiB
18Accepted248ms70120 KiB
19Accepted286ms70176 KiB
20Accepted287ms70260 KiB
21Accepted246ms70216 KiB
22Accepted246ms70120 KiB
23Accepted286ms70160 KiB
24Accepted284ms70072 KiB
25Accepted246ms70120 KiB
26Accepted246ms70120 KiB
subtask420/20
1Accepted282ms70328 KiB
2Accepted250ms70100 KiB
3Accepted246ms70132 KiB
4Accepted282ms70216 KiB
5Accepted246ms70100 KiB
6Accepted244ms70116 KiB
7Accepted284ms70348 KiB
8Accepted282ms70148 KiB
9Accepted245ms70292 KiB
10Accepted246ms70080 KiB
11Accepted284ms70192 KiB
12Accepted284ms70328 KiB
13Accepted246ms70116 KiB
14Accepted244ms70120 KiB
15Accepted250ms70236 KiB
subtask520/20
1Accepted300ms70776 KiB
2Accepted314ms70708 KiB
3Accepted266ms70556 KiB
4Accepted266ms70560 KiB
5Accepted294ms71196 KiB
6Accepted270ms70632 KiB
7Accepted305ms70636 KiB
8Accepted331ms71900 KiB
9Accepted263ms70632 KiB
10Accepted293ms71760 KiB
11Accepted301ms70632 KiB
12Accepted305ms70632 KiB
13Accepted261ms70632 KiB
14Accepted263ms70632 KiB
15Accepted296ms70752 KiB
16Accepted328ms72056 KiB
17Accepted289ms72164 KiB
18Accepted264ms70632 KiB