LeetCode #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 connections[i] = [a, b] represents a connection between servers a and b. Any server can reach any other server directly or indirectly through the network.

critical connection is a connection that, if removed, will make some server 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.

Constraints:

  • 1 <= n <= 10^5
  • n-1 <= connections.length <= 10^5
  • connections[i][0] != connections[i][1]
  • There are no repeated connections.
class Solution {
public:
    vector<vector<int>> criticalConnections(int n, vector<vector<int>>& connections) {
        // u是强连通分量的根的条件:u或u的子树不存在路径可以返回祖先
        // 也就是low[u]<dfsnum[u]&&low[v]<dfsnum[u],v是u的子节点
        num=0; // 节点访问编号
        dfsnum=vector<int>(n+1,0); // dfsnum[i]表示访问该点的时间或编号,值越小表示越早访问到
        low=vector<int>(n+1,0); // low[i]表示i或i的子树可以访问到的节点编号
        visited=vector<bool>(n+1,false);
        parent=vector<int>(n+1,-1); 
        
        for(auto connection:connections)
        {
            graph[connection[0]].push_back(connection[1]);
            graph[connection[1]].push_back(connection[0]);
        }
        vector<vector<int>> result;
        for(int i=1;i<=n;i++)
        {
            if(!visited[i]) tarjan(i,result);
        }
        return result;
    }
    
    void tarjan(int u, vector<vector<int>>& result)
    {
        visited[u]=true;
        num++;
        dfsnum[u]=low[u]=num;
        for(int v: graph[u]) //访问所有出边 
        {
            if(!visited[v]) //不曾访问过,可以认为是子节点了
            {
                parent[v]=u;
                tarjan(v,result); // 递归访问子节点
                low[u]=min(low[u],low[v]);
                if(low[v]>dfsnum[u]) // 发现桥
                    result.push_back({min(u,v),max(u,v)});   
            }
            else if(v!=parent[u]) // 注意判断是否存在回向边,排除重边
                low[u]=min(low[u],dfsnum[v]);
        }
    }
    
private:
    int num;
    vector<int> dfsnum;
    vector<int> low;
    vector<bool> visited;
    vector<int> parent;
    unordered_map<int,vector<int>> graph;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值