a3743e237174098d8ac56d14a32749e78f6ced47
17 int ptrcmp(const void *l
, const void *r
)
19 return ((ptrdiff_t)((struct node
*)l
)->data
)
20 -((ptrdiff_t)((struct node
*)r
)->data
);
23 int nodecmp(const void *l
, const void *r
)
25 return ((ptrdiff_t)l
) -((ptrdiff_t)((struct node
*)r
)->data
);
28 struct components
*strongconnect(struct node
*v
, struct node
**stack
, int *sp
,
29 int *index
, int nedges
, struct edge
*edges
, struct components
*components
)
38 for (int i
= 0; i
<nedges
; i
++) {
39 if (edges
[i
].from
!= v
)
43 components
= strongconnect(w
, stack
, sp
, index
,
44 nedges
, edges
, components
);
45 } else if (w
->onStack
) {
46 v
->lowlink
= min(v
->lowlink
, w
->index
);
50 if (v
->lowlink
== v
->index
) {
51 struct list
*res
= NULL
;
55 res
= list_cons(w
->data
, res
);
57 struct components
*ng
= safe_malloc(sizeof(struct components
));
58 ng
->next
= components
;
59 ng
->nodes
= list_to_array(res
, &ng
->nnodes
, false);
65 struct components
*scc(int nnodes
, void **nodedata
, int nedges
, struct edge
*edgedata
)
67 struct components
*res
= NULL
;
68 struct node
*nodes
= safe_malloc(nnodes
*sizeof(struct node
));
69 for (int i
= 0; i
<nnodes
; i
++)
70 nodes
[i
] = (struct node
){.lowlink
=-1, .index
=-1,
71 .onStack
=false, .data
=nodedata
[i
]};
72 qsort(nodes
, nnodes
, sizeof(struct node
), ptrcmp
);
74 struct edge
*edges
= safe_malloc(nedges
*sizeof(struct edge
));
75 for (int i
= 0; i
<nedges
; i
++) {
76 struct node
*from
= bsearch(edgedata
[i
].from
, nodes
, nnodes
,
77 sizeof(struct node
), nodecmp
);
79 fprintf(stderr
, "edge from references unknown node\n");
82 struct node
*to
= bsearch(edgedata
[i
].to
, nodes
, nnodes
,
83 sizeof(struct node
), nodecmp
);
85 fprintf(stderr
, "edge to references unknown node\n");
88 edges
[i
] = (struct edge
){.from
=from
, .to
=to
};
91 struct node
**stack
= safe_malloc(nnodes
*sizeof(struct node
*));
94 for (int i
= 0; i
< nnodes
; i
++)
95 if (nodes
[i
].index
== -1)
96 res
= strongconnect(&nodes
[i
], stack
, &sp
, &index
,
105 void components_free(struct components
*cs
, void (*freefun
)(void *))
109 for (int i
= 0; i
<cs
->nnodes
; i
++)
110 freefun(cs
->nodes
[i
]);
112 struct components
*t
= cs
->next
;
120 // void *nodes[] = {(void *)1, (void *)2, (void *)3};
121 // struct edge edges[] = {{(void *)1, (void *)2}, {(void *)2, (void *)1}};
122 // struct components *cs = scc(3, &nodes[0], 2, &edges[0]);
123 // FOREACHCOMP(c, cs) {
124 // fprintf(stderr, "comp: ");
125 // for (int i = 0; i<c->nnodes; i++)
126 // fprintf(stderr, "%d, ", c->nodes[i]);
127 // fprintf(stderr, "\n");
129 // components_free(cs, NULL);