# Python program for the above approach
import collections
import functools
# Declaring ordered_set
@functools.total_ordering
class ordered_set:
def __init__(self):
self.tree = collections.defaultdict(set)
def insert(self, val):
self.tree[val] = set()
def __le__(self, other):
return self.tree.keys() <= other.tree.keys()
def __eq__(self, other):
return self.tree.keys() == other.tree.keys()
def order_of_key(self, val):
return len([k for k in self.tree.keys() if k < val])
def erase(self, val):
del self.tree[val]
# Map to store final ans for each node
ans = {}
# Function to add an edge
# between nodes u and v
def addEdge(adj, u, v):
adj[u].append(v)
adj[v].append(u)
# Function to count the number of
# ancestors with values smaller
# than that of the current node
def countSmallerAncestors(adj, root, par, ancestors):
# Map current node to
# number of smaller valued ancestors
ans[root] = ancestors.order_of_key(root)
# Add current node to path
ancestors.insert(root)
for node in adj[root]:
# Avoid cycles
if node != par:
countSmallerAncestors(
adj, node,
root, ancestors)
# Remove current node from path
ancestors.erase(root)
# Driver Code
if __name__ == '__main__':
# Number of nodes in graph
N = 7
# Initialize graph
adj = {i:[] for i in range(1,N+1)}
# Tree Formation
addEdge(adj, 1, 5)
addEdge(adj, 1, 4)
addEdge(adj, 4, 6)
addEdge(adj, 5, 3)
addEdge(adj, 5, 2)
addEdge(adj, 5, 7)
# Ordered set to store values in path
# from root to current node in dfs
ancestors = ordered_set()
countSmallerAncestors(adj, 1, -1, ancestors)
for i in range(1, N+1):
print(ans[i], end=' ')
# # This code is contributed by Vikram_Shirsat