Submission #21273753


Source Code Expand

import sys
import numpy as np
import numba
from numba import njit, b1, i1, i4, i8, f8

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

def from_read(dtype=np.int64):
    return np.fromstring(read().decode(), dtype=dtype, sep=' ')


def from_readline(dtype=np.int64):
    return np.fromstring(readline().decode(), dtype=dtype, sep=' ')

@njit
def max_flow(N, G, source, sink):
    """G は、(from, to, cap) の入った (M,3) array。
    逆辺は持たせなくてよい"""
    M = len(G)
    H = G
    G = np.empty((M + M, 4), np.int64)
    for i in range(M):
        fr, to, cap = H[i]
        G[2 * i] = (fr, to, cap, 0)
        G[2 * i + 1] = (to, fr, 0, 0)
    argsort = np.argsort(G[:, 0])
    rank = np.argsort(argsort)
    G = G[argsort]
    for i in range(M):
        r1 = rank[2 * i]
        r2 = rank[2 * i + 1]
        G[r1, 3] = r2
        G[r2, 3] = r1
    idx = np.searchsorted(G[:, 0], np.arange(N + 1))
    level = np.zeros(N, np.int32)
    prog = np.zeros(N, np.int32)
    deq = np.empty(N, np.int32)
    stack = np.empty((N, 2), np.int64)

    def bfs():
        nonlocal N, G, source, sink, idx, level, prog, deq
        level[:] = 0
        level[source] = 1
        l, r = 0, 0
        deq[r], r = source, r + 1
        while l < r:
            v, l = deq[l], l + 1
            for e in range(idx[v], idx[v + 1]):
                fr, to, cap, rev = G[e]
                if not cap:
                    continue
                if level[to]:
                    continue
                level[to] = level[v] + 1
                if to == sink:
                    return
                deq[r], r = to, r + 1
        return

    def dfs():
        nonlocal N, G, source, sink, idx, level, prog, stack
        INF = 1 << 60
        ascend = False
        ff = 0
        s = 0
        stack[s], s = (source, INF), s + 1
        while s:
            if ff:
                v, f = stack[s - 1]
                s -= 1
                p = prog[v]
                _, to, cap, rev = G[p]
                G[p][2] -= ff
                G[rev][2] += ff
                continue
            v, f = stack[s - 1]
            if v == sink:
                ff = f
                s -= 1
                continue
            if ascend:
                prog[v] += 1
            find = False
            p = prog[v]
            for e in range(p, idx[v + 1]):
                _, to, cap, rev = G[e]
                prog[v] = e
                if not cap:
                    continue
                if level[to] <= level[v]:
                    continue
                find = True
                break
            if not find:
                ascend = True
                s -= 1
                continue
            ascend = False
            x = min(f, cap)
            stack[s], s = (to, x), s + 1
        return ff

    flow = 0
    while True:
        bfs()
        if not level[sink]:
            break
        prog[:] = idx[:N]
        while True:
            f = dfs()
            if not f:
                break
            flow += f
    return flow, G

@njit
def scc_dfs(N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, v):
    low[v] = ord[v] = now_ord
    now_ord += 1
    visited[vis_i], vis_i = v, vis_i + 1
    for e in range(idx[v], idx[v + 1]):
        to = G[e, 1]
        if ord[to] == -1:
            now_ord, group_num, vis_i = \
                scc_dfs(N, G, idx, low, ord, ids,
                        visited, now_ord, group_num,
                        vis_i, to)
            low[v] = min(low[v], low[to])
        else:
            low[v] = min(low[v], ord[to])
    if low[v] == ord[v]:
        while True:
            u, vis_i = visited[vis_i - 1], vis_i - 1
            ord[u] = N
            ids[u] = group_num
            if u == v:
                break
        group_num += 1
    return now_ord, group_num, vis_i


@njit
def scc(N, G):
    idx = np.searchsorted(G[:, 0], np.arange(N + 1))
    low = np.zeros(N, np.int64)
    ord = np.zeros(N, np.int64) - 1
    now_ord = 0
    group_num = 0
    visited, vis_i = np.empty(N, np.int64), 0
    ids = np.zeros(N, np.int64)
    for v in range(N):
        if ord[v] == -1:
            now_ord, group_num, vis_i = \
                scc_dfs(N, G, idx, low, ord, ids,
                        visited, now_ord, group_num,
                        vis_i, v)
    comp = group_num - ids - 1
    n_comp = group_num
    return n_comp, comp

@njit
def bfs_01(N, G, v):
    INF = 1 << 60
    idx = np.searchsorted(G[:, 0], np.arange(N + 2))
    dist = np.full(N + 1, INF, np.int64)
    dist[v] = 0
    q, l, r = np.empty(N + 10, np.int64), 0, 0
    q[r], r = v, r + 1
    while l < r:
        v, l = q[l], l + 1
        for e in range(idx[v], idx[v + 1]):
            w = G[e, 1]
            if dist[w] > dist[v] + 1:
                q[r], r = w, r + 1
                dist[w] = dist[v] + 1
    return dist

@njit((i8, i8[:, :], i8[:, :]), cache=True)
def main(N, G, CD):
    INF = 1 << 60
    flow, res_G = max_flow(N + 1, G, 1, N)
    H = res_G[res_G[:, 2] > 0][:, :2]
    n_comp, comp = scc(N + 1, H)
    """
    topological 順序で、必ず source よりも後ろに来るパターンと、sink よりも前に来るパターン
    """
    after_s = bfs_01(N, H, 1) < INF
    H = H[:, ::-1]
    H = H[np.argsort(H[:, 0], kind='mergesort')]
    before_t = bfs_01(N, H, N) < INF
    comp[after_s] = comp[1]
    comp[before_t] = comp[N]

    for q in range(len(CD)):
        c, d = CD[q]
        if comp[c] == comp[d]:
            print('YES NO')
        elif comp[c] == comp[1] and comp[d] == comp[N]:
            print('NO YES')
        elif comp[d] == comp[1] and comp[c] == comp[N]:
            print('NO YES')
        else:
            print('YES YES')

N, M = from_readline()
nums = from_read()
G = nums[:M + M].reshape(M, 2)
CD = nums[M + M + 1:].reshape(-1, 2)

G = np.append(G, np.ones(M, np.int64).reshape(M, 1), axis=1)

main(N, G, CD)

Submission Info

Submission Time
Task A - 高橋王国と青木王国
User maspy
Language Python (3.8.2)
Score 100
Code Size 6202 Byte
Status AC
Exec Time 792 ms
Memory 120976 KiB

Judge Result

Set Name Sample Dataset1 Dataset2
Score / Max Score 0 / 0 20 / 20 80 / 80
Status
AC × 3
AC × 51
AC × 68
Set Name Test Cases
Sample 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt
Dataset1 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt, 01_30.txt, 01_31.txt, 01_32.txt, 01_33.txt, 01_34.txt, 01_35.txt, 01_36.txt, 01_37.txt, 01_38.txt, 01_39.txt, 01_40.txt, 01_41.txt, 01_42.txt, 01_43.txt, 01_44.txt, 01_45.txt, 01_46.txt, 01_47.txt
Dataset2 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt, 01_30.txt, 01_31.txt, 01_32.txt, 01_33.txt, 01_34.txt, 01_35.txt, 01_36.txt, 01_37.txt, 01_38.txt, 01_39.txt, 01_40.txt, 01_41.txt, 01_42.txt, 01_43.txt, 01_44.txt, 01_45.txt, 01_46.txt, 01_47.txt, 02_00.txt, 02_01.txt, 02_02.txt, 02_03.txt, 02_04.txt, 02_05.txt, 02_06.txt, 02_07.txt, 02_08.txt, 02_09.txt, 02_10.txt, 02_11.txt, 02_12.txt, 02_13.txt, 02_14.txt, 02_15.txt, 02_16.txt
Case Name Status Exec Time Memory
00_sample_01.txt AC 508 ms 109140 KiB
00_sample_02.txt AC 497 ms 109220 KiB
00_sample_03.txt AC 499 ms 108452 KiB
01_00.txt AC 508 ms 108736 KiB
01_01.txt AC 501 ms 108748 KiB
01_02.txt AC 514 ms 108740 KiB
01_03.txt AC 498 ms 108480 KiB
01_04.txt AC 500 ms 108048 KiB
01_05.txt AC 500 ms 109112 KiB
01_06.txt AC 496 ms 108452 KiB
01_07.txt AC 491 ms 108468 KiB
01_08.txt AC 494 ms 108324 KiB
01_09.txt AC 499 ms 109220 KiB
01_10.txt AC 497 ms 108716 KiB
01_11.txt AC 492 ms 108024 KiB
01_12.txt AC 501 ms 108024 KiB
01_13.txt AC 505 ms 108480 KiB
01_14.txt AC 498 ms 108020 KiB
01_15.txt AC 500 ms 108420 KiB
01_16.txt AC 495 ms 108752 KiB
01_17.txt AC 499 ms 108448 KiB
01_18.txt AC 498 ms 109092 KiB
01_19.txt AC 490 ms 108716 KiB
01_20.txt AC 496 ms 108728 KiB
01_21.txt AC 493 ms 108460 KiB
01_22.txt AC 494 ms 108752 KiB
01_23.txt AC 499 ms 108392 KiB
01_24.txt AC 497 ms 108020 KiB
01_25.txt AC 495 ms 109356 KiB
01_26.txt AC 496 ms 108032 KiB
01_27.txt AC 493 ms 109224 KiB
01_28.txt AC 494 ms 108032 KiB
01_29.txt AC 496 ms 109176 KiB
01_30.txt AC 499 ms 108384 KiB
01_31.txt AC 493 ms 108768 KiB
01_32.txt AC 500 ms 108516 KiB
01_33.txt AC 509 ms 108708 KiB
01_34.txt AC 501 ms 109224 KiB
01_35.txt AC 488 ms 108012 KiB
01_36.txt AC 499 ms 108392 KiB
01_37.txt AC 495 ms 108424 KiB
01_38.txt AC 490 ms 108032 KiB
01_39.txt AC 492 ms 108492 KiB
01_40.txt AC 495 ms 108736 KiB
01_41.txt AC 494 ms 109300 KiB
01_42.txt AC 497 ms 108048 KiB
01_43.txt AC 498 ms 108504 KiB
01_44.txt AC 505 ms 108716 KiB
01_45.txt AC 493 ms 108688 KiB
01_46.txt AC 494 ms 108688 KiB
01_47.txt AC 491 ms 108456 KiB
02_00.txt AC 568 ms 110844 KiB
02_01.txt AC 563 ms 111532 KiB
02_02.txt AC 571 ms 111828 KiB
02_03.txt AC 592 ms 113636 KiB
02_04.txt AC 626 ms 120104 KiB
02_05.txt AC 623 ms 120148 KiB
02_06.txt AC 627 ms 120044 KiB
02_07.txt AC 603 ms 119672 KiB
02_08.txt AC 607 ms 120120 KiB
02_09.txt AC 607 ms 120976 KiB
02_10.txt AC 604 ms 119668 KiB
02_11.txt AC 792 ms 119964 KiB
02_12.txt AC 635 ms 120664 KiB
02_13.txt AC 593 ms 120664 KiB
02_14.txt AC 590 ms 118100 KiB
02_15.txt AC 596 ms 118908 KiB
02_16.txt AC 599 ms 120116 KiB