LeetCode //C - 1466. Reorder Routes to Make All Paths Lead to the City Zero

1466. Reorder Routes to Make All Paths Lead to the City Zero

There are n cities numbered from 0 to n - 1 and n - 1 roads such that there is only one way to travel between two different cities (this network form a tree). Last year, The ministry of transport decided to orient the roads in one direction because they are too narrow.

Roads are represented by connections where connections[i] = [ai, bi] represents a road from city ai to city bi.

This year, there will be a big event in the capital (city 0), and many people want to travel to this city.

Your task consists of reorienting some roads such that each city can visit the city 0. Return the minimum number of edges changed.

It’s guaranteed that each city can reach city 0 after reorder.
 

Example 1:

LeetCode //C - 1466. Reorder Routes to Make All Paths Lead to the City Zero_第1张图片

Input: n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]
Output: 3
Explanation: Change the direction of edges show in red such that each node can reach the node 0 (capital).

Example 2:

在这里插入图片描述

Input: n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]
Output: 2
Explanation: Change the direction of edges show in red such that each node can reach the node 0 (capital).

Example 3:

Input: n = 3, connections = [[1,0],[2,0]]
Output: 0

Constraints:
  • 2 < = n < = 5 ∗ 1 0 4 2 <= n <= 5 * 10^4 2<=n<=5104
  • connections.length == n - 1
  • connections[i].length == 2
  • 0 < = a i , b i < = n − 1 0 <= a_i, b_i <= n - 1 0<=ai,bi<=n1
  • a i ! = b i a_i != b_i ai!=bi

From: LeetCode
Link: 1466. Reorder Routes to Make All Paths Lead to the City Zero


Solution:

Ideas:

1. Graph Representation:

  • Each city is represented as a node in the graph.
  • Each road between cities is represented as a directed edge in the graph.
  • The graph is represented using an adjacency list, which is an array of linked lists. The i-th position in the array contains a linked list of Node structures that represent all the cities directly reachable from city i.

2. Node Structure:

  • The Node structure represents an edge in the graph.
  • It contains the destination city (dest), a flag indicating if this edge is reversed (reversed), and a pointer to the next node (next).

3. Graph Creation:

  • The createGraph function creates the graph by initializing the adjacency list and populating it with edges.
  • For each connection from city a to city b, it inserts two nodes into the adjacency lists:
    • One in a’s list with reversed set to true because it’s initially directed away from city 0.
    • Another in b’s list with reversed set to false because it’s directed towards city 0 and doesn’t need to be reversed.

4. Depth-First Search (DFS):

  • The dfs function performs a depth-first search starting from city 0.
  • As it traverses the graph, it checks if an edge is reversed and increments the reversals count accordingly.
  • It uses a visited array to keep track of which cities have been visited to avoid processing a city more than once.

5. Counting Reversals:

  • The minReorder function is the main function that sets up the problem.
  • It creates the graph and then calls dfs to calculate the minimum number of edge reversals needed for all cities to reach city 0.
  • After the dfs call, it frees the dynamically allocated memory.

6. Memory Management:

  • The code carefully allocates and deallocates memory for the graph and auxiliary data structures to avoid memory leaks.
Code:
typedef struct Node {
    int dest;
    bool reversed;
    struct Node* next;
} Node;

typedef struct Graph {
    int n;
    Node** adjList;
} Graph;

Graph* createGraph(int n, int** connections, int connectionsSize) {
    Graph* graph = (Graph*)malloc(sizeof(Graph));
    graph->n = n;
    graph->adjList = (Node**)calloc(n, sizeof(Node*)); // Use calloc to initialize to NULL

    for (int i = 0; i < connectionsSize; i++) {
        // Add edge from a to b
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->dest = connections[i][1];
        newNode->reversed = true; // This edge needs to be reversed
        newNode->next = graph->adjList[connections[i][0]];
        graph->adjList[connections[i][0]] = newNode;
        
        // Add edge from b to a for traversal, no need to reverse
        newNode = (Node*)malloc(sizeof(Node));
        newNode->dest = connections[i][0];
        newNode->reversed = false; // This edge does not need to be reversed
        newNode->next = graph->adjList[connections[i][1]];
        graph->adjList[connections[i][1]] = newNode;
    }

    return graph;
}

void freeGraph(Graph* graph) {
    for (int i = 0; i < graph->n; i++) {
        Node* node = graph->adjList[i];
        while (node) {
            Node* temp = node;
            node = node->next;
            free(temp);
        }
    }
    free(graph->adjList);
    free(graph);
}

int dfs(Graph* graph, bool* visited, int node) {
    visited[node] = true;
    int reversals = 0;

    Node* adjNode = graph->adjList[node];
    while (adjNode != NULL) {
        if (!visited[adjNode->dest]) {
            if (adjNode->reversed) {
                reversals++;
            }
            reversals += dfs(graph, visited, adjNode->dest);
        }
        adjNode = adjNode->next;
    }

    return reversals;
}

int minReorder(int n, int** connections, int connectionsSize, int* connectionsColSize) {
    Graph* graph = createGraph(n, connections, connectionsSize);
    bool* visited = (bool*)calloc(n, sizeof(bool));
    int result = dfs(graph, visited, 0);
    free(visited);
    freeGraph(graph);
    return result;
}

你可能感兴趣的:(LeetCode,leetcode,c语言,算法)