def hitBricks(self, grid, hits):
        """
        :type grid: List[List[int]]
        :type hits: List[List[int]]
        :rtype: List[int]
        """
        m, n = len(grid), len(grid[0])
        # extra dummy node m * n to connect to all nodes in first row
        uf = UnionFind(m * n + 1)
        # mark all hits so that they won't be unioned initially
        for i, j in hits:
            if grid[i][j] == 1:
                grid[i][j] = 2
        # traversing the grid is slow, can improve it with dfs on hit points
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    self.union_around(i, j, grid, uf)
        # number of nodes connected to dummy node after all hits
        count = uf.counts[uf.find(m * n)]
        res = [0] * len(hits)
        # roll back
        for i in range(len(hits) - 1, -1, -1):
            x, y = hits[i]
            if grid[x][y] == 2:
                # add the hit back and union bricks around
                grid[x][y] = 1
                self.union_around(x, y, grid, uf)

            new_count = uf.counts[uf.find(m * n)]
            res[i] = max(new_count - count - 1, 0)
            count = new_count

        return res
Example #2
0
 def findRedundantDirectedConnection(self, edges):
     """
     :type edges: List[List[int]]
     :rtype: List[int]
     """
     uf = UnionFind(len(edges) + 1)
     candidates = self.find_candidates(edges)
     # no nodes have two parents: fall back to Q1
     if not candidates:
         for p, q in edges:
             if uf.find(p) == uf.find(q):
                 return [p, q]
             uf.union(p, q)
     # remove the last edge that makes the graph a valid tree
     else:
         # union all edges except for the second candidate
         # if a cycle is found during the process
         # (not necessarily when the two nodes of first candidates are unioned)
         # the first candidate must be removed
         for p, q in edges:
             if p == candidates[1][0] and q == candidates[1][1]:
                 continue
             if uf.find(p) == uf.find(q):
                 return candidates[0]
             uf.union(p, q)
         return candidates[1]
Example #3
0
 def minMalwareSpread(self, graph, initial):
     """
     :type graph: List[List[int]]
     :type initial: List[int]
     :rtype: int
     """
     if not initial:
         return -1
     # return the smallest index if multiple results
     initial.sort()
     n = len(graph)
     uf = UnionFind(n)
     # union the whole graph
     for i in range(n):
         for j in range(i + 1, n):
             if graph[i][j] == 1:
                 uf.union(i, j)
     # if only one initially infected node, the damage reduced will be the group size
     # => return the infected node in the largest group
     # if 2+ initially infected node in a group, cannot reduce the damage
     # => return the infected node with minimum index
     counter = collections.Counter(
         uf.find(i)
         for i in initial)  # group_parent => # of initially infected nodes
     one_infected = [i for i in initial if counter[uf.find(i)] == 1]
     if one_infected:
         return max(one_infected, key=lambda i: uf.sizes[uf.find(i)])
     else:
         return min(initial)
Example #4
0
class ClusterGraph():
    def __init__(self):
        self.edges = []
        self.union_find = UnionFind()

    def add_edge(self, edge):
        self.edges.append(edge)
        self.union_find.add_element(edge[0])
        self.union_find.add_element(edge[1])

    def clusterfy(self, num_clusters=4):
        self.sort_edges()
        while len(self.union_find.clusters) > num_clusters:
            edge = self.edges.pop()
            leader1 = self.union_find.find(edge[0])
            leader2 = self.union_find.find(edge[1])
            if leader1 != leader2:
                self.union_find.union(leader1, leader2)

    def sort_edges(self):
        self.edges.sort(key=lambda edge: edge[2], reverse=True)

    def get_maximum_spacing(self):
        final_edges = []
        for edge in self.edges:
            leader1 = self.union_find.find(edge[0])
            leader2 = self.union_find.find(edge[1])
            if leader1 != leader2:
                final_edges.append(edge)

        return min(final_edges, key=lambda edge: edge[2])[2]
    def numIslands2(self, m, n, positions):
        """
        :type m: int
        :type n: int
        :type positions: List[List[int]]
        :rtype: List[int]
        """
        uf = UnionFind(m * n)
        added = set()
        count = 0  # current number of islands
        res = []

        for i, j in positions:
            p = i * n + j
            added.add((i, j))
            count += 1

            for x, y in [(i - 1, j), (i, j - 1), (i + 1, j), (i, j + 1)]:
                if 0 <= x < m and 0 <= y < n and (x, y) in added:
                    q = x * n + y
                    # reduce count if two nodes are connected
                    # but currently in different trees
                    if uf.find(p) != uf.find(q):
                        count -= 1
                    uf.union(p, q)

            res.append(count)

        return res
def kruskal(size, weights):
    union_find = UnionFind(size)

    for u, v in sorted(weights, key=weights.get):
        if union_find.find(u) != union_find.find(v):
            union_find.union(u, v)

            yield u, v
Example #7
0
def labeling(char_voxel, bool_voxel):
    # labeling target is boundary voxels
    nonzero = np.nonzero(bool_voxel)
    targets = np.array(nonzero).transpose()
    normals = get_normals(char_voxel, targets)
    idx = np.zeros(char_voxel.shape, dtype=np.int32)
    labels = np.full(char_voxel.shape, -1, dtype=np.int32)
    target_length = targets.shape[0]
    uf = UnionFind(target_length)
    # connection kernel(3x3)
    p1 = [-1, -1, -1, 0, 0, 0, 1, 1, 1]
    p2 = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
    # connection kernel(2x2)
    q1 = [-1, -1, -1, 0, 0]
    q2 = [-1, 0, 1, -1, 0]

    arr = np.arange(target_length)
    print(idx[nonzero].shape)
    idx[nonzero] = arr
    for id, p in enumerate(targets):
        if id % 10000 == 0:
            print(id)
        #idx[p[0], p[1], p[2]] = id
        for i in range(9):
            if labels[p[0], p[1] + p1[i], p[2] + p2[i]] == -1:
                # not in boundary voxel
                continue
            idn = idx[p[0], p[1] + p1[i], p[2] + p2[i]]
            #if 0.1 < np.dot(normals[id,:], normals[idn, :]):
            #    uf.union(idn, id)
            uf.union(idn, id)
        #if p[0]<2 or p[1]<2 or p[2] < 2:

        #    labels[p[0], p[1], p[2]] = uf.find(id)
        #    continue
        for i in range(9):
            if labels[p[0] - 1, p[1] + p1[i], p[2] + p2[i]] == -1:
                # not in boundary voxel
                continue
            idn = idx[p[0] - 1, p[1] + p1[i], p[2] + p2[i]]
            #if 0.1 < np.dot(normals[id,:], normals[idn, :]):
            #    uf.union(idn, id)
            uf.union(idn, id)
        labels[p[0], p[1], p[2]] = uf.find(id)
    # labels lookup table
    lut = np.full(target_length, -1, dtype=np.int32)
    lbl_max = 0
    for i in range(target_length):
        fi = uf.find(i)
        if fi == i and uf.count[i] > 10:
            lut[i] = lbl_max
            lbl_max += 1
    print("label count: {}".format(lbl_max))
    for i in range(target_length):
        fi = uf.find(i)
        if lut[fi] != -1:
            labels[targets[i, 0], targets[i, 1], targets[i, 2]] = lut[fi]
    return labels
Example #8
0
    def test_union_when_already_united(self):
        uf = UnionFind([[1,2,3],[4,5],[6,7,8,9,0]])
        self.assertEqual(uf.find(1), 1)
        self.assertEqual(uf.find(2), 1)

        uf.union(1,2)

        self.assertEqual(uf.find(1), 1)
        self.assertEqual(uf.find(2), 1)
Example #9
0
def build_mst(n, edges):
    # edge (w, (u, v))
    tree_edges = []
    pset = UnionFind(n + 1)
    edges.sort()
    for w, e in edges:
        u, v = e
        if pset.find(u) != pset.find(v):
            pset.union(u, v)
            tree_edges.append((u, v))
    return tree_edges
Example #10
0
    def test_union(self):
        uf = UnionFind([[1,2,3],[4,5],[6,7,8,9,0]])
        self.assertEqual(uf.find(2), 1)
        self.assertEqual(uf.find(5), 4)

        uf.union(2,5)

        self.assertEqual(uf.find(1), 1)
        self.assertEqual(uf.find(2), 1)
        self.assertEqual(uf.find(3), 1)
        self.assertEqual(uf.find(4), 1)
        self.assertEqual(uf.find(5), 1)
Example #11
0
    def findRedundantConnection(self, edges):
        """
        :type edges: List[List[int]]
        :rtype: List[int]
        """

        uf = UnionFind(len(edges) + 1)

        for p, q in edges:
            if uf.find(p) == uf.find(q):
                return [p, q]
            uf.union(p, q)
Example #12
0
def kruskals(g):
    edges = sorted(g.edges, key=lambda e: e[2])
    u = UnionFind()
    # set up all the cities as trees in UF
    for city in g.cities:
        u.makeset(city)
    mst = []
    for e in edges:
        q, v, _ = e
        if u.find(q) != u.find(v):
            mst.append(e)
            u.union(q, v)
    return mst
def mst_kruskal(grafo):
    """Pre: el grafo es no dirigido.
    Retorna un arbol de tendido minimo."""
    conjuntos = UnionFind(grafo.obtener_todos_los_vertices())
    #ordenar las aristas de forma ascendente por peso.
    aristas = sorted(grafo.obtener_todas_las_aristas(), key=itemgetter(2))
    arbol = Grafo(False)
    for v in grafo.obtener_todos_los_vertices():
        arbol.agregar_vertice(v, grafo.ver_dato_vertice(v))
    for v, w, p in aristas:
        if conjuntos.find(v) == conjuntos.find(w): continue
        arbol.agregar_arista(v, w, p)
        conjuntos.union(v, w)
    return arbol
 def validTree(self, n, edges):
     """
     :type n: int
     :type edges: List[List[int]]
     :rtype: bool
     """
     uf = UnionFind(n)
     # no cycles
     for p, q in edges:
         if uf.find(p) == uf.find(q):
             return False
         uf.union(p, q)
     # no forest
     return uf.num_groups == 1
class MinWTFeedbackEdgeSet:
    def __init__(self, g):
        self.edge_set = []
        self.g = g
        self.heap = MaxHeap()
        self.UF = UnionFind(g.V)
        self.populateHeap()
        self.populate_edge_set()

    def populateHeap(self):
        edges = set()
        for i in range(self.g.V):
            for edge in self.g.adj(i):
                edges.add(edge)
        for edge in edges:
            self.heap.add_item(edge)

    def populate_edge_set(self):
        #import pdb; pdb.set_trace()
        while not self.heap.empty():
            edge = self.heap.del_max()
            if not self.UF.find(edge.either(), edge.other(edge.either())):
                self.UF.union(edge.either(), edge.other(edge.either()))
            else:
                self.edge_set.append(edge)
                    
    def get_mst(self):
        return self.edge_set
Example #16
0
def clustering(g, num_nodes, k):
    different_clusters, index = [], 0
    g.sort()
    uf = UnionFind(num_nodes)

    while uf.size() > k:
        cost, u, v = g[index]
        uf.union(u, v)
        index += 1

    for cost, u, v, in g:
        u_leader, v_leader = uf.find(u), uf.find(v)
        if u_leader != v_leader:
            different_clusters.append(cost)

    return min(different_clusters)
Example #17
0
def kruskal(g):
    MST = []
    MST_weight = 0

    # initializing Union Find
    U = UnionFind()
    U.initialize(g.V)

    # initializing heap
    heap = Heap()
    for e in g.E:
        heap.push([e[2], (e[0], e[1])])  # [cost, edge]

    while not (len(MST) == g.n - 1 or heap.is_empty()):
        aux_edge = heap.pop()
        edge = [aux_edge[1][0], aux_edge[1][1], aux_edge[0]]  # v1, v2, cost
        e0_find = U.find(edge[0])
        e1_find = U.find(edge[1])

        if e0_find != e1_find:
            MST.append(edge)
            MST_weight += edge[2]  # weighting MST
            U.union(e0_find, e1_find)

    return MST, MST_weight
Example #18
0
class KruskalsMST:
    def __init__(self, g):
        self.mst = []
        self.g = g
        self.heap = MinHeap()
        self.UF = UnionFind(g.V)
        self.populateHeap()
        self.populate_mst()

    def populateHeap(self):
        edges = set()
        for i in range(self.g.V):
            for edge in self.g.adj(i):
                edges.add(edge)
        for edge in edges:
            self.heap.add_item(edge)

    def populate_mst(self):
        while len(self.mst) < self.g.V - 1 and not self.heap.is_empty():
            edge = self.heap.del_min()
            if not self.UF.find(edge.either(), edge.other(edge.either())):
                self.mst.append(edge)
                self.UF.union(edge.either(), edge.other(edge.either()))

    def get_mst(self):
        return self.mst
Example #19
0
def kruskal(g):
	V = g.number_of_nodes()
	edges = sorted(g.edges(data="weight"), key=lambda x: x[2])
	uf = UnionFind(V)
	mst = [0] * (V-1)

	e = i = 0
	while e < V-1:
		edge = edges[i]
		src, des, _ = edge
		if uf.find(src) != uf.find(des):
			uf.union(src, des)
			mst[e] = (src, des)
			e += 1
		i += 1
		
	return mst
Example #20
0
def kruskal(graph):
    ret = 0
    result = []
    edges = []
    for u in graph:
        for v, c in graph[u]:
            edges.append((u, v, c))
    edges.sort(key=lambda x: x[2])
    uf = UnionFind(len(graph.V))

    for u, v, c in edges:
        if uf.find(u) == uf.find(v):
            continue
        uf.union(u, v)
        result.append((u, v))
        ret += c

    return ret, result
Example #21
0
    def build_disjoint_set(self, num_vertices, edges):
        ds = UnionFind(num_vertices)
        for u, v in edges:
            root_u = ds.find(u)
            root_v = ds.find(v)
            if root_u != root_v:
                ds.join(root_u, root_v)

        return ds
 def test_union_find(self):
     elements = [1, 2, 3, 4, 6, 7, 8]
     u1 = UnionFind(elements)
     for e in elements:
         self.assertEqual(e, u1.find(e))
     new_parent = u1.union(1, 2)
     self.assertEqual(1, new_parent)
     new_parent = u1.union(3, 4)
     self.assertEqual(3, new_parent)
     new_parent = u1.union(2, 4)
     self.assertEqual(1, new_parent)
     self.assertEqual(1, u1.find(4))
     new_parent = u1.union(3, 4)
     self.assertEqual(1, new_parent)
     new_parent = u1.union(3, 8)
     self.assertEqual(1, new_parent)
     new_parent = u1.union(8, 3)
     self.assertEqual(1, new_parent)
class ClusterNodesOnly():
    def __init__(self):
        self.union_find = UnionFind()
        self.one_distances = []
        self.two_distances = []

    def find_all_one_distances(self, node):
        possible_nodes = []
        for bit in range(0, len(node)):
            search_node = node.copy()
            bit_to_change = "0" if node[bit] == '1' else "1"
            search_node[bit] = bit_to_change
            if tuple(search_node) in self.union_find.node_leaders:
                possible_nodes.append(search_node)

        return possible_nodes

    def find_all_two_distances(self, node):
        possible_nodes = []
        for first_bit in range(0, len(node) - 1):
            for second_bit in range(1, len(node)):
                search_node = node.copy()
                first_bit_to_change = "0" if node[first_bit] == "1" else "1"
                second_bit_to_change = "0" if node[second_bit] == "1" else "1"
                search_node[first_bit] = first_bit_to_change
                search_node[second_bit] = second_bit_to_change
                if tuple(search_node) in self.union_find.node_leaders:
                    possible_nodes.append(search_node)

        return possible_nodes

    def add_node(self, node):
        self.union_find.add_element(tuple(node))
        one_distances = self.find_all_one_distances(node)
        for close_node in one_distances:
            self.one_distances.append((node, close_node))
        two_distances = self.find_all_two_distances(node)
        for close_node in two_distances:
            self.two_distances.append((node, close_node))

    def clusterfy(self):
        while len(self.one_distances) > 0 or len(self.two_distances) > 0:
            nodes = self.get_next_pair_of_nodes()
            leader1 = self.union_find.find(tuple(nodes[0]))
            leader2 = self.union_find.find(tuple(nodes[1]))
            if leader1 != leader2:
                self.union_find.union(tuple(leader1), tuple(leader2))
        return len(self.union_find.clusters)

    def get_next_pair_of_nodes(self):
        if len(self.one_distances) > 0:
            return self.one_distances.pop()
        elif len(self.two_distances) > 0:
            return self.two_distances.pop()
        else:
            return None
Example #24
0
    def test_union(self):
        uf = UnionFind([i for i in range(0, 10)])
        unions = [0, 2, 3, 3, 5, 5, 5, 5, 5, 5]
        for i, j in enumerate(unions):
            uf.union(i, j)

        self.assertEqual(uf.ids, [0, 1, 1, 1, 4, 4, 4, 4, 4, 4],
                         msg='Union Find merge incorrect')
        self.assertEqual(
            uf.find(2),
            1,
            msg='Union find incorrect finds the representative class')
Example #25
0
def kruskal(edges, vertices):
    """
    Runs the Kruskal algorithm using the edges and vertices.
    """
    cost = 0
    mst = []
    n = len(vertices)

    # Sort the edges by weight.
    edges = sorted(edges, key=lambda x: x[1])
    uf = UnionFind(vertices)

    for ((u, v), w) in edges:
        # If the edge doesn't create a circle
        if uf.find(u) != uf.find(v):
            # add it to the MST.
            uf.union(u, v)
            mst.append((u, v))
            cost += w
            # Stop when the MST has |V|-1 edges.
            if len(mst) == n - 1:
                return cost, mst
Example #26
0
def add_documents(name: str, event_ids: List[int],
                  tweet_urls: Dict[int, models.URL], session):
    uf = UnionFind()

    tweets = session.query(models.Tweet).filter(
        models.Tweet.event_id_id.in_(event_ids)).all()
    for tweet in tqdm(tweets, desc="Iterating over tweets (create sets)"):
        uf.make_set(tweet.tweet_id)

        url_obj = tweet_urls.get(tweet.tweet_id)
        if url_obj:
            uf.make_set(url_obj.expanded_url)

    for tweet in tqdm(tweets, desc="Iterating over tweets (join sets)"):
        if tweet.in_reply_to_status_id:
            uf.union(tweet.tweet_id, int(tweet.in_reply_to_status_id))
        if tweet.retweet_of_id:
            uf.union(tweet.tweet_id, int(tweet.retweet_of_id))

        url_obj = tweet_urls.get(tweet.tweet_id)
        if url_obj:
            uf.union(tweet.tweet_id, url_obj.expanded_url)

    with session.begin():
        group_doc = dict()
        groups = map(lambda g: str(uf.find(g)), uf.groups)
        for rep in groups:
            document = models.Document(url=rep)
            group_doc[rep] = document

        for tweet in tqdm(tweets,
                          desc="Iterating over tweets (set documents)"):
            id = str(uf.find(tweet.tweet_id))
            doc = group_doc[id]

            tweet.document = doc

    return uf
Example #27
0
class UnionFind2:
    def __init__(self, groups, fn):
        self.fn = fn
        g = []
        for group in groups:
            g.append(map(fn, group))
        self.uf = UnionFind(g)

    def find(self, item):
        return self.uf.find(self.fn(item))

    def union(self, item_1, item_2):
        self.uf.union(self.fn(item_1), self.fn(item_2))

    def get_clusters(self):
        return self.uf.leader_to_group.values()
Example #28
0
class UnionFind2:
    def __init__(self, groups, fn):
        self.fn = fn
        g = []
        for group in groups:
            g.append(map(fn, group))
        self.uf = UnionFind(g)

    def find(self, item):
        return self.uf.find(self.fn(item))

    def union(self, item_1, item_2):
        self.uf.union(self.fn(item_1), self.fn(item_2))

    def get_clusters(self):
        return self.uf.leader_to_group.values()
Example #29
0
def kruskal(nodes:List(Int), edges:List(Tuple(Int, Int, Int)), edges_to_check:List(Tuple(Int, Int)))\
        ->List(Tuple(Int, Int, Int)):
    sets = UnionFind({})
    mst = []
    for n in nodes:
        sets.add_node(n)

    for e in sorted(edges, key=itemgetter(2)):
        n1 = e[0]
        n2 = e[1]
        l1 = sets.find(n1)
        l2 = sets.find(n2)
        if l1 != l2:
            (e1, e2, w) = e
            if ((e1, e2) in edges_to_check) or (e2, e1) in edges_to_check:
                mst.append(e)
            sets.union(l1, l2)
    return mst
Example #30
0
def kruskal(nodes:List(Int), edges:List(Tuple(Int, Int, Int)), edges_to_check:List(Tuple(Int, Int)))\
        ->List(Tuple(Int, Int, Int)):
    sets = UnionFind({})
    mst = []
    for n in nodes:
        sets.add_node(n)

    for e in sorted(edges, key=itemgetter(2)):
        n1 = e[0]
        n2 = e[1]
        l1 = sets.find(n1)
        l2 = sets.find(n2)
        if l1 != l2:
            (e1, e2, w) = e
            if ((e1, e2) in edges_to_check) or (e2, e1) in edges_to_check:
                mst.append(e)
            sets.union(l1, l2)
    return mst
Example #31
0
    def test_find(self):
        uf = UnionFind([[1,2,3],[4,5],[6,7,8,9,0]])
        self.assertEqual(uf.find(1), 1)
        self.assertEqual(uf.find(2), 1)
        self.assertEqual(uf.find(3), 1)

        self.assertEqual(uf.find(4), 4)
        self.assertEqual(uf.find(5), 4)

        self.assertEqual(uf.find(6), 6)
        self.assertEqual(uf.find(7), 6)
        self.assertEqual(uf.find(8), 6)
        self.assertEqual(uf.find(9), 6)
        self.assertEqual(uf.find(0), 6)
Example #32
0
    def accountsMerge(self, accounts):
        """
        :type accounts: List[List[str]]
        :rtype: List[List[str]]
        """
        email_to_id, id_to_name = self.create_mappings(accounts)
        uf = UnionFind(len(email_to_id))

        # union emails within an account
        for account in accounts:
            p = email_to_id[account[1]]
            for i in range(2, len(account)):
                q = email_to_id[account[i]]
                uf.union(p, q)

        # collect emails by tree
        for email, p in email_to_id.iteritems():
            parent = uf.find(p)
            id_to_emails[parent].append(email)

        return [[id_to_name[p]] + sorted(emails) for p, emails in id_to_emails.items()]
Example #33
0
    def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
        n = len(s)
        uf = UnionFind(n)
        roots = []
        for pair in pairs:
            uf.union(pair[0], pair[1])
        # now we have the indices organized into connected components
        connected_components: DefaultDict[int, List[str]] = defaultdict(list)
        for i in range(n):
            roots.append(uf.find(i))
            connected_components[roots[i]].append(s[i])
        # we need to sort each connected component alphabetically
        for root, chars in connected_components.items():
            connected_components[root] = sorted(chars)
        # now we can iterate through the string, find the root of each
        # index, and put the highest ranked element in that component
        # at that index
        smallest_str = []
        for i in range(n):
            smallest_str.append(connected_components[roots[i]].pop(0))

        return "".join(smallest_str)
Example #34
0
def test_union_find():
    uf = UnionFind(5)
    assert(uf.find(0) != uf.find(1))
    assert(uf.find(0) == uf.find(0))
    assert(uf.find(0) != uf.find(2))
    assert(uf.n_subset == 5)

    uf.union(1, 0)
    assert(uf.is_same_subset(0, 1))
    assert(not uf.is_same_subset(0, 2))
    assert(uf.n_subset == 4)

    uf.union(2, 4)
    subsets = uf.get_subsets()
    expected_subsets = [{0, 1}, {2, 4}, {3}]
    assert(len(subsets) == len(expected_subsets))
    for i in expected_subsets:
        assert(i in subsets)

    uf.union(2, 3)
    uf.union(3, 4)
    uf.union(0, 4)
    assert(uf.find(1) == uf.find(3))
    assert(uf.n_subset == 1)
Example #35
0
assert uf.nsets == 5

uf.union(0, 1)

assert uf.nsets == 4

uf.union(2, 3)

assert uf.nsets == 3

uf.union(4, 3)

assert uf.nsets == 2
assert uf.connected(0, 3) == False
assert uf.connected(4, 3) == True

p_expected = [1, 1, 3, 3, 3]
size_expected = [2, 2, 3, 3, 3]
for i in range(5):
    assert uf.find(i) == p_expected[i]
    assert uf.set_size(i) == size_expected[i]

uf.union(0, 3)

assert uf.nsets == 1
p_expected = [3] * 5
size_expected = [5] * 5
for i in range(5):
    assert uf.find(i) == p_expected[i]
    assert uf.set_size(i) == size_expected[i]
Example #36
0
is_prime = [ True ]*(n+1)

def Furui(n):
	p = 0
	is_prime[0] = False
	is_prime[1] = False
	for i in xrange(2, n+1):
		if is_prime[i]:
			prime[p] = i
			p += 1
			for j in xrange(2*i, n+1, i):
				is_prime[j] = False
	return p

p = Furui(n)

if __name__ == '__main__':
	l = B - A + 1
	U = UnionFind(l)

	for i in xrange(p):
		if prime[i] >= P:
			start = (A + prime[i] - 1) / prime[i] * prime[i]
			end = B / prime[i] * prime[i]
			for j in xrange(start, end+1, prime[i]):
				U.union(start-A, j-A)
	res = 0
	for i in xrange(A, B+1):
		if (U.find(i-A) == i-A): res += 1
	print res
Example #37
0
		(1, 1, 3),
		(2, 3, 1),
		(1, 5, 5),
	]

	s = UnionFind(3*N)

	ans = 0
	for i in xrange(K):
		t = info[i][0]
		x = info[i][1]-1
		y = info[i][2]-1
		if x < 0 or x >= N or y < 0 or y >= N:
			ans += 1
			continue
		rx = s.find(x)
		ry = s.find(y)
		print rx, ry
		ry1 = s.find(y+N)
		ry2 = s.find(y+2*N)
		if t == 1:
			if rx == ry1 or rx == ry2:
				ans += 1
			else:
				s.union(x, y)
				s.union(x + N, y + N)
				s.union(x+2*N, y+2*N)
		else:
			if rx == ry or rx == ry2:
				ans += 1
			else: