Leetcode1319. Number of operations connected to the network (medium, BFS, DFS)

content

1. Topic description

2. Problem solving analysis

3. Code implementation


1. Topic description

n Connect each computer into a network  with an Ethernet cable  , and the computers are numbered from 0 to  n-1. The cable is  connections indicated by , where  connections[i] = [a, b] the computer  a and  the b.

Any computer in the network can directly or indirectly access any other computer in the same network through the network.

To give you the initial wiring for this computer network  connections, you can unplug the cable between any two directly connected computers and use it to connect a pair of computers that are not directly connected. Please calculate and return the minimum number of operations required to connect all computers. Returns -1 if not possible. 

Example 1:

Input: n = 4, connections = [[0,1],[0,2],[1,2]]
 Output: 1
 Explanation: Unplug the cable between computer 1 and 2 and plug it into the computer 1 and 3 on.

Example 2:

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

Example 3:

Input: n = 6, connections = [[0,1],[0,2],[0,3],[1,2]]
 Output: -1
 Explanation: Insufficient number of cables.

Example 4:

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

hint:

  • 1 <= n <= 10^5
  • 1 <= connections.length <= min(n*(n-1)/2, 10^5)
  • connections[i].length == 2
  • 0 <= connections[i][0], connections[i][1] < n
  • connections[i][0] != connections[i][1]
  • There are no duplicate connections.
  • Two computers are not connected by multiple cables. 

2. Problem solving analysis

        connections相当于是图的edge列表表示。

        First impression, this problem cannot be done in a constructive way, like trying to move the edges one way or the other to turn the whole graph into a connected graph, and see which solution requires the least number of operations. It should be solved in a manner similar to existence proofs in mathematics.

        (1) Assuming that the number of edges is sufficient, if there are k islands (that is, k separate connected regions) in the original graph, (k-1) edges are required to turn the entire graph into a connected graph, so (k-1) operations are required. Remember the number of islands as K_{island}.

        (2) After determining the number of islands in the original image, it is necessary to determine whether the original image has enough redundant edges to fill the islands.

        (3) The same principle as in (1), in order to make a total of N nodes connected with the minimum number of edges to become a fully connected graph, at least N-1 edges are required.

        Therefore, it is only necessary to compare whether the original number of edges and the number of nodes in the original graph satisfy the above (3) conditions to determine whether there are enough edges. Of course, there is also a link to prove that under the condition that the number of edges is sufficient, the movement can always K_{island}-1be completed in one operation and the network becomes a fully connected graph. See Section 4 below.

        The search for the number of islands is more convenient based on the representation of the adjacency list, so it can be based onconnections先构建邻接列表(adjacence list),然后再基于临界列表通过广度或深度搜索搜索岛屿个数。

       

3. Code implementation

from typing import List
from collections import deque
class Solution:
    def makeConnected(self, n: int, connections: List[List[int]]) -> int:

        # Construct the adjacency list
        adjList = dict()
        for edge in connections:
            if edge[0] in adjList:
                adjList[edge[0]].append(edge[1])
            else:
                adjList[edge[0]] = [edge[1]]

            if edge[1] in adjList:
                adjList[edge[1]].append(edge[0])
            else:
                adjList[edge[1]] = [edge[0]]
        # n_nodes = len(adjList)
        n_edges = len(connections)
        
        # print(adjList)
        
        if n_edges < n-1:
            return -1
        
        # Count the number of islands
        visited = set()
        n_islands = 0
        for k in range(n):
            if k not in visited:
                q = deque()
                q.append(k)
                visited.add(k)
                if k in adjList:
                    while len(q)>0:
                        m = q.pop()
                        # print(k,m,adjList[m])
                        for j,adjnode in enumerate(adjList[m]):
                            if adjnode not in visited:
                                q.append(adjnode)
                                visited.add(adjnode)
                n_islands += 1
        
        return n_islands-1
    
if __name__ == '__main__':
    
    sln = Solution()
    
    n = 4
    connections = [[0,1],[0,2],[1,2]]
    print(sln.makeConnected(n,connections))
        
    n = 6
    connections = [[0,1],[0,2],[0,3],[1,2],[1,3]]
    print(sln.makeConnected(n,connections))
    
    n = 6
    connections = [[0,1],[0,2],[0,3],[1,2]]
    print(sln.makeConnected(n,connections))
    
    n = 5
    connections = [[0,1],[0,2],[3,4],[2,3]]
    print(sln.makeConnected(n,connections))

        Execution time: 120 ms, beat 71.63% of users in all Python3 commits

        Memory consumption: 35 MB, beats 27.67% of users across all Python3 commits

4. Proof of Feasibility

        When there are k separate connected regions in the graph, is there a way to move k−1 lines? The following is a constructive proof (the strict proof itself is still a bit troublesome, so here is a direct excerpt of the leetcode official solution proof for your reference)

        We can find that m computers only need m−1 wires to connect them. If the number of edges in a connected component with m nodes exceeds m−1, a redundant edge must be found, and the connectivity remains unchanged after removing this edge. At this point, we can use this edge to connect two connected components, reducing the number of connected components in the graph by 1.

        In the example 2 given by the question, there are 5 edges in the connected component {0,1,2,3}, which is greater than m−1=3. So an extra edge must be found. Specifically, after any edge in the connected component is removed, the connectivity remains unchanged.

        Note: Not in all cases, any edge in the connected component can be removed, we just need to ensure that "one" redundant edge must be found.

        So we can design an iterative process: each time we find a redundant edge in the graph, disconnect it, and connect the two connected components in the graph. Repeating this process k−1 times will eventually make the entire graph connected.

        How can we guarantee that "one" redundant edge will be found? What we need to prove is that at any time, if there are k ′ connected components in the graph and k'>1, that is, the whole graph is not completely connected, then there must be a connected component that makes it have an extra edge: that is, it The number of nodes is m_i, the number of edges is e_i, and is satisfied e_i > m_i-1.

        We can use proof by contradiction to prove the above conclusion. Assuming that all connected components are satisfied e_i \ le m_i-1, then:

 

 

Author: LeetCode-Solution
Link: https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected/solution/lian-tong-wang-luo-de-cao-zuo-ci -shu-by-leetcode-s/
Source: The copyright of LeetCode
belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source.

        Back to the main directory: Leetcode daily problem-solving notes (dynamic update...)

Guess you like

Origin blog.csdn.net/chenxy_bwave/article/details/124199154