結果
問題 | No.1640 簡単な色塗り |
ユーザー |
![]() |
提出日時 | 2023-05-17 01:43:32 |
言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
結果 |
AC
|
実行時間 | 725 ms / 2,000 ms |
コード長 | 15,125 bytes |
コンパイル時間 | 429 ms |
コンパイル使用メモリ | 14,208 KB |
実行使用メモリ | 52,096 KB |
最終ジャッジ日時 | 2024-12-14 22:52:22 |
合計ジャッジ時間 | 26,523 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 52 TLE * 1 |
ソースコード
import sysreadline=sys.stdin.readlinefrom collections import defaultdictclass UnionFind:def __init__(self,N,label=None,f=None,weighted=False):self.N=Nself.parents=[None]*self.Nself.size=[1]*self.Nself.roots={i for i in range(self.N)}self.label=labelif self.label!=None:self.label=[x for x in label]self.f=fself.weighted=weightedif self.weighted:self.weight=[0]*self.Ndef Find(self,x):stack=[]while self.parents[x]!=None:stack.append(x)x=self.parents[x]if self.weighted:w=0for y in stack[::-1]:self.parents[y]=xw+=self.weight[y]self.weight[y]=welse:for y in stack[::-1]:self.parents[y]=xreturn xdef Union(self,x,y,w=None):root_x=self.Find(x)root_y=self.Find(y)if root_x==root_y:if self.weighted:if self.weight[y]-self.weight[x]==w:return Trueelse:return Falseelse:if self.size[root_x]<self.size[root_y]:x,y=y,xroot_x,root_y=root_y,root_xif self.weighted:w=-wself.parents[root_y]=root_xself.size[root_x]+=self.size[root_y]self.roots.remove(root_y)if self.label!=None:self.label[root_x]=self.f(self.label[root_x],self.label[root_y])if self.weighted:self.weight[root_y]=w+self.weight[x]-self.weight[y]def Size(self,x):return self.size[self.Find(x)]def Same(self,x,y):return self.Find(x)==self.Find(y)def Label(self,x):return self.label[self.Find(x)]def Weight(self,x,y):root_x=self.Find(x)root_y=self.Find(y)if root_x!=root_y:return Nonereturn self.weight[y]-self.weight[x]def Roots(self):return list(self.roots)def Linked_Components_Count(self):return len(self.roots)def Linked_Components(self):linked_components=defaultdict(list)for x in range(self.N):linked_components[self.Find(x)].append(x)return linked_componentsdef __str__(self):linked_components=defaultdict(list)for x in range(self.N):linked_components[self.Find(x)].append(x)return "\n".join(f"{r}: {m}" for r,m in linked_components.items())class 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=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 MIV_DFS(self,initial_vertices=None,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):if initial_vertices==None:initial_vertices=[s for s in range(self.V)]seen=[False]*self.Vfinished=[False]*self.Vif bipartite_graph:bg=[None]*self.Vcnt=-1if 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 bipartite_graph or unweighted_dist:uwd=[self.inf]*self.Vif weighted_dist:wd=[self.inf]*self.Vfor s in initial_vertices:if seen[s]:continueif bipartite_graph:cnt+=1bg[s]=(cnt,0)if linked_components:lc.append([])if bipartite_graph or unweighted_dist:uwd[s]=0if weighted_dist:wd[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[-1].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 bipartite_graph:bg[y]=(cnt,bg[x][1]^1)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 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_=bgbg=[[[],[]] for i in range(cnt+1)]for tpl in self.edges:i,j=tpl[:2] if self.weighted else tplif not bg_[i][1]^bg_[j][1]:bg[bg_[i][0]]=Falsefor x in range(self.V):if bg[bg_[x][0]]:bg[bg_[x][0]][bg_[x][1]].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 retuN=int(readline())used=[False]*Ncnt=[0]*Ngraph=[[] for x in range(N)]for i in range(N):a,b=map(int,readline().split())a-=1;b-=1graph[a].append((b,i))graph[b].append((a,i))cnt[a]+=1cnt[b]+=1ans_lst=[None]*Nif 0 in cnt:print("No")exit()stack=[x for x in range(N) if cnt[x]==1]while stack:x=stack.pop()for y,i in graph[x]:if not used[i]:cnt[x]-=1ans_lst[i]=x+1used[i]=Truecnt[y]-=1if cnt[y]==1:stack.append(y)breakelse:print("No")exit()for x in range(N):if cnt[x]==0:continuewhile cnt[x]:for y,i in graph[x]:if not used[i]:cnt[x]-=1cnt[y]-=1ans_lst[i]=x+1used[i]=Truex=ybreakprint("Yes")print(*ans_lst,sep="\n")