結果
問題 | No.277 根掘り葉掘り |
ユーザー |
![]() |
提出日時 | 2023-02-19 08:28:23 |
言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
結果 |
AC
|
実行時間 | 630 ms / 3,000 ms |
コード長 | 8,980 bytes |
コンパイル時間 | 101 ms |
コンパイル使用メモリ | 13,568 KB |
実行使用メモリ | 55,228 KB |
最終ジャッジ日時 | 2024-07-20 10:55:17 |
合計ジャッジ時間 | 8,423 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 18 |
ソースコード
import sysreadline=sys.stdin.readlinefrom collections import defaultdict,dequeclass 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 SIV_BFS(self,s,bfs_tour=False,bipartite_graph=False,linked_components=False,parents=False,unweighted_dist=False,weighted_dist=False):seen=[False]*self.Vseen[s]=Trueif bfs_tour:bt=[s]if linked_components:lc=[s]if parents:ps=[None]*self.Vif unweighted_dist or bipartite_graph:uwd=[self.inf]*self.Vuwd[s]=0if weighted_dist:wd=[self.inf]*self.Vwd[s]=0queue=deque([s])while queue:x=queue.popleft()for y in self.graph[x]:if self.weighted:y,d=yif not seen[y]:seen[y]=Truequeue.append(y)if bfs_tour:bt.append(y)if linked_components:lc.append(y)if parents:ps[y]=xif unweighted_dist or bipartite_graph:uwd[y]=uwd[x]+1if weighted_dist:wd[y]=wd[x]+dif bipartite_graph:bg=[[],[]]for tpl in self.edges:i,j=tpl[:2] if self.weighted else tplif uwd[i]==self.inf or uwd[j]==self.inf:continueif not uwd[i]%2^uwd[j]%2:bg=Falsebreakelse:for x in range(self.V):if uwd[x]==self.inf:continuebg[uwd[x]%2].append(x)retu=()if bfs_tour:retu+=(bt,)if bipartite_graph:retu+=(bg,)if linked_components:retu+=(lc,)if parents:retu+=(ps,)if unweighted_dist:retu+=(uwd,)if weighted_dist:retu+=(wd,)if len(retu)==1:retu=retu[0]return retudef Tree_Diameter(self,weighted=False):def Farthest_Point(u):dist=self.SIV_BFS(u,weighted_dist=True) if weighted else self.SIV_BFS(u,unweighted_dist=True)fp=0for i in range(self.V):if dist[fp]<dist[i]:fp=ireturn fp,dist[fp]u,d=Farthest_Point(0)v,d=Farthest_Point(u)return u,v,dN=int(readline())edges=[]for _ in range(N-1):u,v=map(int,readline().split())u-=1;v-=1edges.append((u,v))G=Graph(N,edges=edges)ans_lst=G.SIV_DFS(0,unweighted_dist=True)for x in range(N):if len(G.graph[x])==1:edges.append((N,x))G=Graph(N+1,edges=edges)dist=G.SIV_BFS(N,unweighted_dist=True)for x in range(N):ans_lst[x]=min(ans_lst[x],dist[x]-1)print(*ans_lst,sep="\n")