classDisjointset definitialize(n) @set=(0..n).to_a @cnt=n; end defgetroot(i) i=@set[i]whilei!=@set[i] returni end defsame?(i,j) getroot(i)==getroot(j) end defunion(i,j) @cnt-=1 b=getroot(j) i,@set[i]=@set[i],bwhile@set[i]!=b j,@set[j]=@set[j],bwhile@set[j]!=b end attr_reader:cnt end
어떤 두 원소가 같은 그룹에 속해 있는지 알아낼 수 있고, 빠른 시간에 그룹을 결합할 수 있는 자료구조인 서로소 집합입니다. Kruskal 등의 알고리즘을 구현할 때 많이 쓰입니다.
$Inf=999999999999999 classPair includeComparable definitialize(first=0,second=0) @first,@second=first,second end defto_s() "(%d, %d)"%[first,second] end attr_reader:first,:second end
classNetwork definitialize() @net=Hash.new(nil) end defplusedge(s,e,value) @net[s]=@net[s]||Hash.new(nil) @net[s][e]=value end defadd(s,e,value) plusedge(s,e,value) plusedge(e,s,value) end attr_accessor:net defdup Marshal::load(Marshal.dump(self)) end end classMaxflow defaugment(pos,ed,m=$Inf) returnfalseif(@check&(1<<pos))!=0 @check^=(1<<pos) ifpos==ed: @m=m; returntrue else @G.net[pos].eachdo|to,val| nextif(val==0) @path[to]=pos returntrueif(augment(to,ed,m>val?val:m)) end end @check^=(1<<pos) false end
deffordfulkerson(ed,t) ret=0 @G=t.dup while(augment(1,ed))do @check=0 pos=ed ret+=@m while(pos!=1)do prev=@path[pos].to_i @G.net[prev][pos]-=@m @G.net[pos][prev]+=@m pos=prev end end ret end definitialize() @check=0 @path=[] end end