LC 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree

Posted feiief

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LC 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree相关的知识,希望对你有一定的参考价值。

link
技术图片
referenct to @617280219

  1. Sort and group edges by weight. In each step we process one group of edges
  2. Discard the edges whose ends are already connected
  3. Run Tarjan‘s bridge finding algorithm on each connnected part of the subgraph. Add bridges to critical and the rest to pseudo-critical
  4. Use union-find to connect the edges‘ two ends.
class Solution {
public:
    struct Edge{
        int u;
        int v;
        int id;
    };
    int N;
    int fa[100];
    int cri[200];
    int pcri[200];
    int dict[100];
    int low[100];
    int timer;
    
    int find(int p){
        if(p==fa[p]) return p;
        fa[p]=find(fa[p]);
        return fa[p];
    }
    
    bool uni(int p, int q){
        int proot=find(p);
        int qroot=find(q);
        if(proot==qroot) return false;
        fa[proot]=qroot;
        return true;
    }
    
    void tarjan(int u,  vector<vector<pair<int,int>>> &adj, int parent){
        ++timer;
        dict[u]=low[u]=timer;
        for(auto& p:adj[u]){
            if(p.first==parent) continue;
            if(dict[p.first]!=-1){
                low[u]=min(low[u],dict[p.first]);
            }else{
                tarjan(p.first,adj,u);
                if(dict[u]<low[p.first] && pcri[p.second]!=1){
                    cri[p.second]=1;
                }
                low[u]=min(low[u],low[p.first]);
            }
        }
    }
    
    vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {
        int en=edges.size();
        N=n;
        map<int,vector<Edge>> mp;
        for(int i=0;i<en;i++){
            auto &e=edges[i];
            mp[e[2]].push_back(Edge{e[0],e[1],i});
        }
        for(int i=0;i<N;i++) fa[i]=i;
        for(auto& m:mp){
            vector<Edge>& es=m.second;
            unordered_map<int,vector<int>> pathes;
            for(auto& e:es){
                int ur=find(e.u);
                int vr=find(e.v);
                if(ur==vr) continue;
                if(ur<vr) swap(ur,vr);
                pathes[ur*N+vr].push_back(e.id);
            }
            vector<vector<pair<int,int>>> adj(N);
            vector<Edge> n_edges;
            for(auto& p:pathes){
                if(p.second.size()>1){
                    for(int i:p.second) pcri[i]=1;
                }
                int ur=p.first/N;
                int vr=p.first%N;
                int id=p.second[0];
                adj[ur].push_back({vr,id});
                adj[vr].push_back({ur,id});
                n_edges.push_back(Edge{ur,vr,id});
                uni(ur,vr);
            }
            memset(dict,-1,sizeof(dict));
            timer=0;
            for(auto& e:n_edges){
                if(dict[e.u]==-1){
                    tarjan(e.u,adj,-1);
                }
            }
            for(auto& e:n_edges){
                if(cri[e.id]==0) pcri[e.id]=1;
            }
        }
        vector<vector<int>> res;
        vector<int> res1,res2;
        for(int i=0;i<en;i++) {
            if(cri[i]) res1.push_back(i);
            else if(pcri[i]) res2.push_back(i);
        }
        res.push_back(res1);
        res.push_back(res2);
        return res;
    }
};


以上是关于LC 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree的主要内容,如果未能解决你的问题,请参考以下文章

LC 384. Shuffle an Array

[LC] 384. Shuffle an Array

LC.162.Find Peak Element

[LC] 1002. Find Common Characters

[LC] 215. Kth Largest Element in an Array

LC 802. Find Eventual Safe States