結果
問題 | No.768 Tapris and Noel play the game on Treeone |
ユーザー |
![]() |
提出日時 | 2022-05-28 17:37:06 |
言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
結果 |
AC
|
実行時間 | 990 ms / 2,000 ms |
コード長 | 8,422 bytes |
コンパイル時間 | 243 ms |
コンパイル使用メモリ | 13,568 KB |
実行使用メモリ | 41,840 KB |
最終ジャッジ日時 | 2024-09-20 23:16:49 |
合計ジャッジ時間 | 15,769 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 22 |
ソースコード
import sysreadline=sys.stdin.readlineclass Graph:def __init__(self,V,edges=False,graph=False,directed=False,weighted=False,inf=float("inf")):self.V=Vself.directed=directedself.weighted=weightedself.inf=infif graph:self.graph=graphself.edges=[]for i in range(self.V):if self.weighted:for j,d in self.graph[i]:if self.directed or not self.directed and i<=j:self.edges.append((i,j,d))else:for j in self.graph[i]:if self.directed or not self.directed and i<=j:self.edges.append((i,j))else:self.edges=edgesself.graph=[[] for i in range(self.V)]if weighted:for i,j,d in self.edges:self.graph[i].append((j,d))if not self.directed:self.graph[j].append((i,d))else:for i,j in self.edges:self.graph[i].append(j)if not self.directed:self.graph[j].append(i)def SIV_DFS(self,s,bipartite_graph=False,cycle_detection=False,directed_acyclic=False,euler_tour=False,linked_components=False,lowlink=False,parents=False,postorder=False,preorder=False,subtree_size=False,topological_sort=False,unweighted_dist=False,weighted_dist=False):seen=[False]*self.Vfinished=[False]*self.Vif directed_acyclic or cycle_detection or topological_sort:dag=Trueif euler_tour:et=[]if linked_components:lc=[]if lowlink:order=[None]*self.Vll=[None]*self.Vidx=0if parents or cycle_detection or lowlink or subtree_size:ps=[None]*self.Vif postorder or topological_sort:post=[]if preorder:pre=[]if subtree_size:ss=[1]*self.Vif unweighted_dist or bipartite_graph:uwd=[self.inf]*self.Vuwd[s]=0if weighted_dist:wd=[self.inf]*self.Vwd[s]=0stack=[(s,0)] if self.weighted else [s]while stack:if self.weighted:x,d=stack.pop()else:x=stack.pop()if not seen[x]:seen[x]=Truestack.append((x,d) if self.weighted else x)if euler_tour:et.append(x)if linked_components:lc.append(x)if lowlink:order[x]=idxll[x]=idxidx+=1if preorder:pre.append(x)for y in self.graph[x]:if self.weighted:y,d=yif not seen[y]:stack.append((y,d) if self.weighted else y)if parents or cycle_detection or lowlink or subtree_size:ps[y]=xif unweighted_dist or bipartite_graph:uwd[y]=uwd[x]+1if weighted_dist:wd[y]=wd[x]+delif not finished[y]:if (directed_acyclic or cycle_detection or topological_sort) and dag:dag=Falseif cycle_detection:cd=(y,x)elif not finished[x]:finished[x]=Trueif euler_tour:et.append(~x)if lowlink:bl=Truefor y in self.graph[x]:if self.weighted:y,d=yif ps[x]==y and bl:bl=Falsecontinuell[x]=min(ll[x],order[y])if x!=s:ll[ps[x]]=min(ll[ps[x]],ll[x])if postorder or topological_sort:post.append(x)if subtree_size:for y in self.graph[x]:if self.weighted:y,d=yif y==ps[x]:continuess[x]+=ss[y]if bipartite_graph:bg=[[],[]]for tpl in self.edges:x,y=tpl[:2] if self.weighted else tplif uwd[x]==self.inf or uwd[y]==self.inf:continueif not uwd[x]%2^uwd[y]%2:bg=Falsebreakelse:for x in range(self.V):if uwd[x]==self.inf:continuebg[uwd[x]%2].append(x)retu=()if bipartite_graph:retu+=(bg,)if cycle_detection:if dag:cd=[]else:y,x=cdcd=self.Route_Restoration(y,x,ps)retu+=(cd,)if directed_acyclic:retu+=(dag,)if euler_tour:retu+=(et,)if linked_components:retu+=(lc,)if lowlink:retu=(ll,)if parents:retu+=(ps,)if postorder:retu+=(post,)if preorder:retu+=(pre,)if subtree_size:retu+=(ss,)if topological_sort:if dag:tp_sort=post[::-1]else:tp_sort=[]retu+=(tp_sort,)if unweighted_dist:retu+=(uwd,)if weighted_dist:retu+=(wd,)if len(retu)==1:retu=retu[0]return retudef Build_Rerooting(self,s,f_transition,f_merge):self.rerooting_s=sself.rerooting_f_transition=f_transitionself.rerooting_f_merge=f_mergeparents,postorder,preorder=self.SIV_DFS(s,parents=True,postorder=True,preorder=True)self.rerooting_lower_dp=[None]*self.Vfor x in postorder:self.rerooting_lower_dp[x]=self.rerooting_f_merge([self.rerooting_f_transition(self.rerooting_lower_dp[y]) for y in G.graph[x] if y!=parents[x]])self.rerooting_upper_dp=[None]*self.Vfor x in preorder:children=[y for y in self.graph[x] if y!=parents[x]]left_accumule_f=[None]*(len(children)+1)right_accumule_f=[None]*(len(children)+1)left_accumule_f[0]=self.rerooting_f_merge([])for i in range(1,len(children)+1):left_accumule_f[i]=self.rerooting_f_merge([left_accumule_f[i-1],self.rerooting_f_transition(self.rerooting_lower_dp[children[i-1]])])right_accumule_f[len(children)]=self.rerooting_f_merge([])for i in range(len(children)-1,-1,-1):right_accumule_f[i]=self.rerooting_f_merge([right_accumule_f[i+1],self.rerooting_f_transition(self.rerooting_lower_dp[children[i]])])for i in range(len(children)):if parents[x]!=None:self.rerooting_upper_dp[children[i]]=self.rerooting_f_merge([left_accumule_f[i],right_accumule_f[i+1],self.rerooting_f_transition(self.rerooting_upper_dp[x])])else:self.rerooting_upper_dp[children[i]]=self.rerooting_f_merge([left_accumule_f[i],right_accumule_f[i+1]])def Rerooting(self,x):if x==self.rerooting_s:retu=self.rerooting_lower_dp[x]else:retu=self.rerooting_f_merge([self.rerooting_lower_dp[x],self.rerooting_f_transition(self.rerooting_upper_dp[x])])return retuN=int(readline())edges=[]for _ in range(N-1):a,b=map(int,readline().split())a-=1;b-=1edges.append((a,b))def trans(x):return not xdef merge(lst):if any(lst):return Truereturn FalseG=Graph(N,edges=edges)G.Build_Rerooting(0,trans,merge)ans_lst=[]for x in range(N):if not G.Rerooting(x):ans_lst.append(x+1)print(len(ans_lst))for ans in ans_lst:print(ans)