static char sccsid
[] = "@(#)2.head.c 4.1 (Berkeley) 2/11/83";
set head[v] to ITERVX heading smallest loop containing v, for each v
/* define ANC(v,w) true if v == w or v is ancestor of w */
#define ANC(v,w) (ntobef[v] <= ntobef[w] && ntoaft[v] <= ntoaft[w]) /* reflexive ancestor */
VERT v
, w
, adj
; int i
, j
;
/* search nodes in reverse of after numbering so that all paths from
a node to an ancestor are searched before the node */
/* at any point, the current value of head allows chains of nodes
to be reached from any node v by taking head[v], head[head[v]], etc.
until an UNDEFINED value is reached. Upon searching each arc,
the appropriate chains must be merged to avoid losing information.
For example, from one path out of a node v it may be known that
v is in a loop headed by z, while from another
it may be known that v is in a loop headed by w.
Thus, head[v] must be set to whichever of z,w is the closer ancestor,
and the fact that this node is in a loop headed by the other must be
for (v
= 0; v
< nodenum
; ++v
)
for (i
= accessnum
-1; i
>= 0; --i
)
for (j
= 0; j
< ARCNUM(v
); ++j
)
if (!DEFINED(adj
)) continue;
if (ntoaft
[adj
] < i
) /* back edge */
else if (ANC(v
,adj
)) /* not back edge or cross edge */
/* need to do only tree edges - must not do edge (v,adj)
when head[adj] is not ANC of v */
if (DEFINED(head
[adj
]) && ANC(head
[adj
],v
))
if (NTYPE(v
) == LOOPVX
|| NTYPE(v
) == DOVX
)
head
[ARC(v
,0)] = head
[v
]; /* head of ITERVX must be different ITERVX */
lowanc(y
,z
,head
) /* find the first node in chain of y which is anc of z, if it exists */
while (y
!= -1 && !ANC(y
,z
))
merge(w
,y
,head
) /* merge chains of w and y according to ANC relation */
if (ANC(w
,y
)) /* set t to min of w,y */
while (w
!= -1 && y
!= -1) /* construct chain at t by adding min of remaining elts */
if (w
== -1) min
= y
; else min
= w
;
if (t
!= min
) head
[t
] = min
;