結果
問題 | No.1002 Twotone |
ユーザー |
![]() |
提出日時 | 2024-07-17 14:23:48 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 4,976 ms / 5,000 ms |
コード長 | 9,383 bytes |
コンパイル時間 | 475 ms |
コンパイル使用メモリ | 82,156 KB |
実行使用メモリ | 357,280 KB |
最終ジャッジ日時 | 2024-07-17 14:25:19 |
合計ジャッジ時間 | 79,931 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 33 |
ソースコード
from collections import defaultdictclass Graph:def __init__(self,V,edges=None,graph=None,directed=False,weighted=False,inf=float("inf")):self.V=Vself.directed=directedself.weighted=weightedself.inf=infif graph!=None:self.graph=graph"""self.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 Centroid(self,root=0):x=rootparents,size=self.SIV_DFS(x,parents=True,subtree_size=True)while True:for y in self.graph[x]:if self.weighted:y,d=yif y==parents[x]:continueif size[y]*2>size[root]:x=ybreakelse:for y in self.graph[x]:if self.weighted:y,d=yif y==parents[x]:continueif size[root]<=2*size[y]:return x,yreturn x,Nonedef Centroid_Decomposition(self):E=self.edgesP=[i for i in range(self.V)]prev_centroid=Nonestack=[(E,P,prev_centroid)]ans=0while stack:E,P,prev_centroid=stack.pop()if len(P)==1:centroid=P[0]continueG=Graph(len(P),edges=E,weighted=self.weighted)centroid,_=G.Centroid()parents,tour=G.SIV_DFS(centroid,parents=True,preorder=True)dp=[None]*len(P)dp_C=[None]*len(P)dp_C[centroid]=tuple()EE=[]PP=[]for i,x in enumerate(G.graph[centroid]):if G.weighted:x,d=xdp[x]=(i,0)EE.append([])PP.append([P[x]])dp_C[x]=(d,)for x in tour[1:]:for y in G.graph[x]:if G.weighted:y,d=yif y==parents[x]:continuei,j=dp[x]jj=len(PP[i])EE[i].append((j,jj,d))PP[i].append(P[y])dp[y]=(i,jj)if len(dp_C[x])>=3 or d in dp_C[x]:dp_C[y]=dp_C[x]else:dp_C[y]=dp_C[x]+(d,)tpls=[]dct=[[] for i in range(len(P))]for p,c in zip(dp,dp_C):if p==None:continuedct[p[0]].append(c)tpls.append(c)if len(c)==2:ans+=1ans+=cnt(tpls)for lst in dct:ans-=cnt(lst)centroid=P[centroid]for E,P in zip(EE,PP):stack.append((E,P,centroid))return ansdef cnt(dp_C):cnt1=defaultdict(int)cnt2=defaultdict(int)c1=0for tpl in dp_C:if len(tpl)==1:cnt1[tpl[0]]+=1c1+=1elif len(tpl)==2:a,b=tplif a>b:a,b=b,acnt2[(a,b)]+=1retu=0retu+=c1*(c1-1)//2for c in cnt1.values():retu-=c*(c-1)//2for (a,b),c in cnt2.items():retu+=c*(c-1)//2retu+=(cnt1[a]+cnt1[b])*creturn retuN,K=map(int,input().split())edges=[]for i in range(N-1):u,v,c=map(int,input().split())u-=1;v-=1edges.append((u,v,c))G=Graph(N,edges=edges,weighted=True)ans=G.Centroid_Decomposition()print(ans)