1192. Critical Connections in a Network
There are n servers numbered from 0 to n - 1 connected by undirected server-to-server connections forming a network where c o n n e c t i o n s i = a i , b i connectionsi = a_i, b_i connectionsi=ai,bi represents a connection between servers a i a_i ai and b i b_i bi. Any server can reach other servers directly or indirectly through the network.
A critical connection is a connection that, if removed, will make some servers unable to reach some other server.
Return all critical connections in the network in any order.
Example 1:

Input: n = 4, connections = \[0,1,1,2,2,0,1,3]
Output: \[1,3]
Explanation: \[3,1] is also accepted.
Example 2:
Input: n = 2, connections = \[0,1]
Output: \[0,1]
Constraints:
- 2 < = n < = 10 5 2 <= n <= 10^5 2<=n<=105
- n − 1 < = c o n n e c t i o n s . l e n g t h < = 10 5 n - 1 <= connections.length <= 10^5 n−1<=connections.length<=105
- 0 < = a i , b i < = n − 1 0 <= a_i, b_i <= n - 1 0<=ai,bi<=n−1
- a i ! = b i a_i != b_i ai!=bi
- There are no repeated connections.
From: LeetCode
Link: 1192. Critical Connections in a Network
Solution:
Ideas:
use Tarjan DFS; edge u-v is critical when lowv > discu.
Code:
c
#include <stdlib.h>
#include <string.h>
int *head, *to, *nextEdge;
int edgeCnt;
int *disc, *low;
int timeCnt;
int **ans;
int ansCnt;
int min(int a, int b) {
return a < b ? a : b;
}
void addEdge(int u, int v) {
to[edgeCnt] = v;
nextEdge[edgeCnt] = head[u];
head[u] = edgeCnt++;
}
void dfs(int u, int parentEdge) {
disc[u] = low[u] = ++timeCnt;
for (int e = head[u]; e != -1; e = nextEdge[e]) {
int v = to[e];
if ((e ^ 1) == parentEdge) continue;
if (disc[v] == 0) {
dfs(v, e);
low[u] = min(low[u], low[v]);
if (low[v] > disc[u]) {
ans[ansCnt] = malloc(sizeof(int) * 2);
ans[ansCnt][0] = u;
ans[ansCnt][1] = v;
ansCnt++;
}
} else {
low[u] = min(low[u], disc[v]);
}
}
}
int** criticalConnections(int n, int** connections, int connectionsSize,
int* connectionsColSize, int* returnSize,
int** returnColumnSizes) {
head = malloc(sizeof(int) * n);
to = malloc(sizeof(int) * connectionsSize * 2);
nextEdge = malloc(sizeof(int) * connectionsSize * 2);
disc = calloc(n, sizeof(int));
low = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) head[i] = -1;
edgeCnt = 0;
for (int i = 0; i < connectionsSize; i++) {
int u = connections[i][0];
int v = connections[i][1];
addEdge(u, v);
addEdge(v, u);
}
ans = malloc(sizeof(int*) * connectionsSize);
ansCnt = 0;
timeCnt = 0;
dfs(0, -1);
*returnSize = ansCnt;
*returnColumnSizes = malloc(sizeof(int) * ansCnt);
for (int i = 0; i < ansCnt; i++) {
(*returnColumnSizes)[i] = 2;
}
free(head);
free(to);
free(nextEdge);
free(disc);
free(low);
return ans;
}