def get_providers_with_resource(ctx, rc_name, amount, tree_root_uuid=None):
    """Returns a set of tuples of (provider UUID, root provider UUID) of
    providers that satisfy the request for a single resource class.

    :param ctx: Session context to use
    :param rc_name: Name of the resource class to check inventory for
    :param amount: Amount of resource being requested
    :param tree_root_uuid: An optional root provider UUID. If provided, the
                           results are limited to the resource providers under
                           the given root resource provider.
    """
    tree_root_clause = ""
    if tree_root_uuid:
        tree_root_clause = " {uuid: '%s'}" % tree_root_uuid
    query = """
            MATCH (root:RESOURCE_PROVIDER{rt})-[*0..99]->
                (rp:RESOURCE_PROVIDER)-[:PROVIDES]->(rc:{rc_name})
            WITH root, rp, rc, ((rc.total - rc.reserved) * rc.allocation_ratio)
                AS capacity
            OPTIONAL MATCH par=(parent:RESOURCE_PROVIDER)-
                [:CONTAINS|ASSOCIATED*]->(root)
            WITH root, size(relationships(par)) AS numrel, rp, rc, capacity
            OPTIONAL MATCH p=(:CONSUMER)-[:USES]->(rc)
            WITH root, numrel, rp, rc, capacity, last(relationships(p)) AS uses
            WITH root, numrel, rp, rc, capacity - sum(uses.amount) AS avail
            WHERE avail >= {amount}
            AND rc.min_unit <= {amount}
            AND rc.max_unit >= {amount}
            AND {amount} % rc.step_size = 0
            AND numrel IS null
            RETURN rp.uuid AS rp_uuid, root.uuid AS root_uuid
    """.format(rt=tree_root_clause, rc_name=rc_name, amount=amount)
    result = ctx.tx.run(query).data()
    return set((rec["rp_uuid"], rec["root_uuid"]) for rec in result)