/* 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; }
static void measure_distance(Agnode_t * n, Agnode_t * ancestor, int dist, Agnode_t * change) { Agnode_t *parent; parent = TPARENT(ancestor); if (parent == NULL) return; dist++; /* check parent to see if it has other leaf paths at greater distance than the context node. set the path/distance of the leaf at this ancestor node */ if (DISTONE(parent) == 0) { LEAFONE(parent) = n; DISTONE(parent) = dist; } else if (dist > DISTONE(parent)) { if (LEAFONE(parent) != change) { if (!DISTTWO(parent) || (LEAFTWO(parent) != change)) change = LEAFONE(parent); LEAFTWO(parent) = LEAFONE(parent); DISTTWO(parent) = DISTONE(parent); } LEAFONE(parent) = n; DISTONE(parent) = dist; } else if (dist > DISTTWO(parent)) { LEAFTWO(parent) = n; DISTTWO(parent) = dist; return; } else return; measure_distance(n, parent, dist, change); }
void prData(Agnode_t * n, int pass) { char *pname; char *bname; char *tname; char *name1; char *name2; int dist1, dist2; if (PARENT(n)) pname = agnameof(PARENT(n)); else pname = "<P0>"; if (BLOCK(n)) bname = agnameof(BLOCK(n)->sub_graph); else pname = "<B0>"; fprintf(stderr, "%s: %x %s %s ", agnameof(n), FLAGS(n), pname, bname); switch (pass) { case 0: fprintf(stderr, "%d %d\n", VAL(n), LOWVAL(n)); break; case 1: if (TPARENT(n)) tname = agnameof(TPARENT(n)); else tname = "<ROOT>"; dist1 = DISTONE(n); if (dist1 > 0) name1 = agnameof(LEAFONE(n)); else name1 = "<null>"; dist2 = DISTTWO(n); if (dist2 > 0) name2 = agnameof(LEAFTWO(n)); else name2 = "<null>"; fprintf(stderr, "%s %s %d %s %d\n", tname, name1, dist1, name2, dist2); break; default: fprintf(stderr, "%d\n", POSITION(n)); break; } }