File tree Expand file tree Collapse file tree 1 file changed +71
-0
lines changed Expand file tree Collapse file tree 1 file changed +71
-0
lines changed Original file line number Diff line number Diff line change @@ -923,6 +923,77 @@ def all(self) -> List[List[int]]:
923923 return res
924924
925925
926+ from typing import List
927+
928+
929+ class PotentialUnionFind :
930+ def __init__ (self , n : int ) -> None :
931+ """
932+ 重み付きunionfind
933+ 俗に言う、牛ゲー
934+
935+ uniteは、差を指定して、uniteします
936+ """
937+ self .data : List [int ] = [- 1 ] * n
938+ self .pot : List [int ] = [0 ] * n
939+
940+ def root (self , vtx : int ) -> int :
941+ """
942+ 頂点vtxの親を出力します
943+ ポテンシャルは出力しません
944+ """
945+ if self .data [vtx ] < 0 :
946+ return vtx
947+
948+ rt = self .root (self .data [vtx ])
949+ self .pot [vtx ] += self .pot [self .data [vtx ]]
950+ self .data [vtx ] = rt
951+
952+ return rt
953+
954+ def potential (self , vtx : int ) -> int :
955+ """
956+ 頂点vtxのポテンシャルを出力します
957+ """
958+ self .root (vtx )
959+
960+ return self .pot [vtx ]
961+
962+ def same (self , a : int , b : int ) -> bool :
963+ """
964+ 頂点aと頂点bが同じ連結成分かを判定します
965+ """
966+ return self .root (a ) == self .root (b )
967+
968+ def unite (self , a : int , b : int , p : int ) -> bool :
969+ """
970+ 頂点aから頂点bを、pの距離でmergeします
971+ 計算量はlog nです
972+ """
973+ p += self .potential (b ) - self .potential (a )
974+ a , b = self .root (a ), self .root (b )
975+
976+ if a == b :
977+ return False
978+
979+ if self .data [a ] < self .data [b ]:
980+ a , b = b , a
981+ p *= - 1 # ポテンシャルもswapします
982+
983+ self .data [b ] += self .data [a ]
984+ self .data [a ] = b
985+ self .pot [a ] = p
986+
987+ return True
988+
989+ def diff (self , a : int , b : int ) -> int :
990+ """
991+ 頂点aから頂点bの距離を、出力します
992+ """
993+
994+ return self .potential (a ) - self .potential (b )
995+
996+
926997# Trie木
927998class Trie :
928999 class Data :
You can’t perform that action at this time.
0 commit comments