結果
問題 | No.1813 Magical Stones |
ユーザー |
![]() |
提出日時 | 2022-01-15 00:02:41 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 869 ms / 2,000 ms |
コード長 | 4,220 bytes |
コンパイル時間 | 210 ms |
コンパイル使用メモリ | 82,444 KB |
実行使用メモリ | 120,704 KB |
最終ジャッジ日時 | 2024-11-20 16:16:07 |
合計ジャッジ時間 | 17,316 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 40 |
ソースコード
import sys#input = sys.stdin.readline #文字列につけてはダメinput = sys.stdin.buffer.readline #文字列につけてはダメ#sys.setrecursionlimit(1000000)#import bisect#import itertools#import randomfrom heapq import heapify, heappop, heappush#from collections import defaultdict#from collections import deque#import copy#import math#from functools import lru_cache#MOD = pow(10,9) + 7#MOD = 998244353class UnionFind(object):def __init__(self, n=1):self.par = [i for i in range(n)]self.rank = [0 for _ in range(n)]self.size = [1 for _ in range(n)]def find(self, x):"""x が属するグループを探索して親を出す。"""if self.par[x] == x:return xelse:self.par[x] = self.find(self.par[x])return self.par[x]def union(self, x, y):"""x と y のグループを結合"""x = self.find(x)y = self.find(y)if x != y:if self.rank[x] < self.rank[y]:x, y = y, xif self.rank[x] == self.rank[y]:self.rank[x] += 1self.par[y] = xself.size[x] += self.size[y]def is_same(self, x, y):"""x と y が同じグループか否か"""return self.find(x) == self.find(y)def get_size(self, x):"""x が属するグループの要素数"""x = self.find(x)return self.size[x]def topological(graph, deg):start = []for i in range(len(deg)):if deg[i] == 0:start.append(i)topo = []while start:v = start.pop()topo.append(v)for u in graph[v]:deg[u] -= 1if deg[u] == 0:start.append(u)return topo#https://atcoder.jp/contests/arc030/submissions/20496099より拝借def scc_dfs1(s, links, status, postorder):stack = [s]status[s] = 0while stack:v = stack[-1]limit = len(links[v])while status[v] < limit:u = links[v][status[v]]status[v] += 1if status[u] != -1:continuestack.append(u)status[u] = 0breakelse:stack.pop()postorder.append(v)returndef scc_dfs2(s, rev_links, status):stack = [s]status[s] = -1scc = [s]while stack:v = stack.pop()for u in rev_links[v]:if status[u] != -1:stack.append(u)status[u] = -1scc.append(u)scc.reverse() #ループの順番が正の順番になるようにする。#要注意return sccdef strongly_connected_components(n, links, rev_links):status = [-1] * npostorder = []for v in range(n):if status[v] != -1:continuescc_dfs1(v, links, status, postorder)postorder.reverse()sccs = []for v in postorder:if status[v] == -1:continuesccs.append(scc_dfs2(v, rev_links, status))# label。不要なら消しても良い。label = [-1] * nfor i in range(len(sccs)):for x in sccs[i]:label[x] = ireturn sccs, label #DAG順になったグループごとのリスト, 頂点が何番目のグループにいるかdef main():N,M = map(int,input().split())G = [[] for _ in range(N)]RG = [[] for _ in range(N)]uf = UnionFind(N)for i in range(M):a,b = map(int,input().split())a -= 1; b -= 1G[a].append(b)RG[b].append(a)uf.union(a,b)L, label = strongly_connected_components(N,G,RG)if len(L) == 1:print(0);exit()#print(label)IN = [0]*len(L)OUT = [0]*len(L)for v in range(N):for u in G[v]:if label[v] == label[u]: continueIN[label[v]] += 1for u in RG[v]:if label[v] == label[u]: continueOUT[label[v]] += 1#print(IN,OUT)ans = max(IN.count(0), OUT.count(0))print(ans)if __name__ == '__main__':main()