/* find_longest_path: * Find and return longest path in tree. */ static nodelist_t* find_longest_path(Agraph_t* tree) { Agnode_t* n; Agedge_t* e; Agnode_t* common = 0; nodelist_t* path; nodelist_t* endPath; int maxlength = 0; int length; if (agnnodes(tree) == 1) { path = mkNodelist(); n = agfstnode(tree); appendNodelist(path, NULL, n); SET_ONPATH(n); return path; } for(n = agfstnode(tree); n; n = agnxtnode(tree, n)) { int count = 0; for(e = agfstedge(tree, n); e; e = agnxtedge(tree, e, n)) { count++; } if(count == 1) measure_distance(n, n, 0, NULL); } /* find the branch node rooted at the longest path */ for(n = agfstnode(tree); n; n = agnxtnode(tree, n)) { length = DISTONE(n) + DISTTWO(n); if(length > maxlength) { common = n; maxlength = length; } } path = mkNodelist(); for (n = LEAFONE(common); n != common; n = TPARENT(n)) { appendNodelist(path, NULL, n); SET_ONPATH(n); } appendNodelist(path, NULL, common); SET_ONPATH(common); if (DISTTWO(common)) { /* 2nd path might be empty */ endPath = mkNodelist(); for (n = LEAFTWO(common); n != common; n = TPARENT(n)) { appendNodelist(endPath, NULL, n); SET_ONPATH(n); } reverseAppend(path, endPath); } return path; }
/* place_node: * Add n to list. By construction, n is not in list at start. */ static void place_node(Agraph_t * g, Agnode_t * n, nodelist_t * list) { Agedge_t *e; int placed = 0; nodelist_t *neighbors = mkNodelist(); nodelistitem_t *one, *two; for (e = agfstout(g, n); e; e = agnxtout(g, e)) { appendNodelist(neighbors, NULL, e->head); SET_NEIGHBOR(e->head); } for (e = agfstin(g, n); e; e = agnxtin(g, e)) { appendNodelist(neighbors, NULL, e->tail); SET_NEIGHBOR(e->tail); } /* Look for 2 neighbors consecutive on list */ if (sizeNodelist(neighbors) >= 2) { for (one = list->first; one; one = one->next) { if (one == list->last) two = list->first; else two = one->next; if (NEIGHBOR(one->curr) && NEIGHBOR(two->curr)) { appendNodelist(list, one, n); placed = 1; break; } } } /* Find any neighbor on list */ if (!placed && sizeNodelist(neighbors) > 0) { for (one = list->first; one; one = one->next) { if (NEIGHBOR(one->curr)) { appendNodelist(list, one, n); placed = 1; break; } } } if (!placed) appendNodelist(list, NULL, n); for (one = neighbors->first; one; one = one->next) UNSET_NEIGHBOR(one->curr); freeNodelist(neighbors); }