Здесь действительно две проблемы: во-первых, вам нужно разработать алгоритм, который вы будете использовать для решения этой проблемы, и, во-вторых, вам нужно его реализовать (в Python).
Алгоритм
Я предполагаю, что вы хотите максимальное собрание ветвей; то есть один раз, к которому вы не можете добавить больше веток. Если вы этого не сделаете, вы можете рассмотреть все подмножества максимальной коллекции.
Следовательно, для дочернего узла мы хотим взять как можно больше ветвей, при условии ограничения, что никакие два родительских узла не имеют общего корня. Другими словами, у каждого ребенка у вас может быть не более одного ребра в окрестности каждого корневого узла. Кажется, это говорит о том, что вы хотите выполнить итерации сначала по дочерним элементам, а затем по (окрестностям) корневых узлов и, наконец, по ребрам между ними. Эта концепция дает следующий псевдокод:
for each child node:
for each root node:
remember each permissible edge
find all combinations of permissible edges
Код
>>> import networkx as nx
>>> import itertools
>>>
>>> G = nx.DiGraph()
>>> G.add_nodes_from(["r0", "r1", "p0", "p1", "p2", "p3", "p4", "c0", "c1", "c2"])
>>> G.add_edges_from([("r0", "p0"), ("r0", "p1"), ("r1", "p2"), ("r1", "p3"),
... ("r1", "p4"), ("p0", "c0"), ("p1", "c1"), ("p2", "c1"),
... ("p3", "c2"), ("p4", "c2")])
>>>
>>> combs = set()
>>> leaves = [node for node in G if not G.out_degree(node)]
>>> roots = [node for node in G if not G.in_degree(node)]
>>> for leaf in leaves:
... for root in roots:
... possibilities = tuple(edge for edge in G.in_edges_iter(leaf)
... if G.has_edge(root, edge[0]))
... if possibilities: combs.add(possibilities)
...
>>> combs
set([(('p1', 'c1'),),
(('p2', 'c1'),),
(('p3', 'c2'), ('p4', 'c2')),
(('p0', 'c0'),)])
>>> print list(itertools.product(*combs))
[(('p1', 'c1'), ('p2', 'c1'), ('p3', 'c2'), ('p0', 'c0')),
(('p1', 'c1'), ('p2', 'c1'), ('p4', 'c2'), ('p0', 'c0'))]
Кажется, вышеприведенное работает, хотя я не проверял.