码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-06-28 09:37:19      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:link   min   doc   nio   nec   air   ini   bool   algorithm   

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

标签:link   min   doc   nio   nec   air   ini   bool   algorithm   

原文地址:https://www.cnblogs.com/FEIIEF/p/13201025.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!