-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconnectedComponents.c
More file actions
113 lines (93 loc) · 2.83 KB
/
connectedComponents.c
File metadata and controls
113 lines (93 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <stdio.h>
#include "graph.h"
#include "connectedComponents.h"
struct ShallowGraph* getComp(struct Vertex* v, int compNumber, struct ShallowGraph* comp, struct ListPool* lp) {
struct VertexList* e;
v->lowPoint = compNumber;
for (e=v->neighborhood; e!=NULL; e=e->next) {
/* go to the vertex, if it was not visited before */
if (e->endPoint->lowPoint == -1) {
getComp(e->endPoint, compNumber, comp, lp);
}
/* add e = (v,w) to comp, if v<w. This is to have only one
copy of each edge in comp */
if (e->startPoint->number < e->endPoint->number) {
pushEdge(comp, shallowCopyEdge(e, lp));
}
}
return comp;
}
void markComp(struct Vertex* v, int compNumber) {
struct VertexList* e;
v->lowPoint = compNumber;
for (e=v->neighborhood; e!=NULL; e=e->next) {
if (e->endPoint->lowPoint == -1) {
markComp(e->endPoint, compNumber);
}
}
}
/* returns a list of shallowgraphs that each contain the edges of a connected
component of the graph (each edge is contained only once as a -> b, where a->number < b->number)
If there is an isolated vertex v in the graph, then there will be a Shallowgraph c with
c->m == 0 and c->data == i->number. */
struct ShallowGraph* getConnectedComponents(struct Graph* g, struct ShallowGraphPool* sgp) {
int v;
int i = 0;
struct ShallowGraph* result = NULL;
for (v=0; v<g->n; ++v) {
g->vertices[v]->lowPoint = -1;
}
for (v=0; v<g->n; ++v) {
if (g->vertices[v]->lowPoint == -1) {
struct ShallowGraph* comp = getComp(g->vertices[v], i, getShallowGraph(sgp), sgp->listPool);
comp->next = result;
result = comp;
++i;
}
/* there might be connected components consisting of a single vertex.
in this case, we store its number in the -> data field of the shallow graph */
if (g->vertices[v]->neighborhood == NULL) {
result->data = v;
}
}
return result;
}
/**
Returns a list of vertices who are roots of connected components.
Result is a shallow graph. each edge->endPoint is pointing to a vertex
belonging to a unique connected component. */
struct ShallowGraph* getRepresentativeVertices(struct Graph* g, struct ShallowGraphPool* sgp) {
int v;
int i = 0;
struct ShallowGraph* result = getShallowGraph(sgp);
for (v=0; v<g->n; ++v) {
g->vertices[v]->lowPoint = -1;
}
for (v=0; v<g->n; ++v) {
if (g->vertices[v]->lowPoint == -1) {
struct VertexList* e = getVertexList(sgp->listPool);
pushEdge(result, e);
e->endPoint = g->vertices[v];
markComp(g->vertices[v], i);
++i;
}
}
return result;
}
char isConnected(struct Graph* g) {
int v;
/* the empty graph is connected: for all pairs of vertices (there are none) there is a path :) */
if (g->n == 0) {
return 1;
}
for (v=0; v<g->n; ++v) {
g->vertices[v]->lowPoint = -1;
}
markComp(g->vertices[0], 0);
for (v=0; v<g->n; ++v) {
if (g->vertices[v]->lowPoint == -1) {
return 0;
}
}
return 1;
}