結果

問題 No.2435 Order All Company
ユーザー lam6er
提出日時 2025-03-20 20:19:57
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 181 ms / 2,000 ms
コード長 2,883 bytes
コンパイル時間 183 ms
コンパイル使用メモリ 82,440 KB
実行使用メモリ 78,188 KB
最終ジャッジ日時 2025-03-20 20:20:48
合計ジャッジ時間 5,336 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 36
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys
from collections import defaultdict

MOD = 998244353

def main():
    N, K = map(int, sys.stdin.readline().split())
    company_freq = []
    for _ in range(K):
        t_i = int(sys.stdin.readline())
        freq = defaultdict(int)
        for __ in range(t_i):
            a, b = map(int, sys.stdin.readline().split())
            if a > b:
                a, b = b, a
            u = a - 1  # convert to 0-based
            v = b - 1
            if u != v:
                freq[(u, v)] += 1
        company_freq.append(freq)
    
    ans = 0
    for mask in range(0, 1 << K):
        size_S = bin(mask).count('1')
        allowed = []
        for i in range(K):
            if not (mask & (1 << i)):
                allowed.append(i)
        
        total_freq = defaultdict(int)
        for i in allowed:
            for (u, v), cnt in company_freq[i].items():
                total_freq[(u, v)] += cnt
        
        # Build Laplacian matrix
        n = N
        laplacian = [[0] * n for _ in range(n)]
        for (u, v), cnt in total_freq.items():
            if u == v:
                continue
            laplacian[u][u] = (laplacian[u][u] + cnt) % MOD
            laplacian[v][v] = (laplacian[v][v] + cnt) % MOD
            laplacian[u][v] = (laplacian[u][v] - cnt) % MOD
            laplacian[v][u] = (laplacian[v][u] - cnt) % MOD
        
        if n <= 1:
            det = 1 if n == 0 else 0  # handle edge cases (though N >=2 per input)
        else:
            minor = [row[1:] for row in laplacian[1:]]
            size_minor = len(minor)
            if size_minor == 0:
                det = 0
            else:
                mat = [row.copy() for row in minor]
                det = 1
                sign = 1
                n_det = len(mat)
                for i in range(n_det):
                    pivot_row = -1
                    for r in range(i, n_det):
                        if mat[r][i] != 0:
                            pivot_row = r
                            break
                    if pivot_row == -1:
                        det = 0
                        break
                    if pivot_row != i:
                        mat[i], mat[pivot_row] = mat[pivot_row], mat[i]
                        sign = (-sign) % MOD
                    pivot_val = mat[i][i]
                    det = (det * pivot_val) % MOD
                    inv_pivot = pow(pivot_val, MOD-2, MOD)
                    for r in range(i+1, n_det):
                        factor = (mat[r][i] * inv_pivot) % MOD
                        for c in range(i, n_det):
                            mat[r][c] = (mat[r][c] - factor * mat[i][c]) % MOD
                det = (det * sign) % MOD
        
        contribution = (pow(-1, size_S, MOD) * det) % MOD
        ans = (ans + contribution) % MOD
    
    print(ans % MOD)

if __name__ == '__main__':
    main()
0