zoukankan      html  css  js  c++  java
  • LC 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree (tarjan, 最小生成树)

    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;
        }
    };
    
  • 相关阅读:
    java核心学习(二十七) 多线程---线程相关类
    java核心学习(二十六) 多线程---线程池
    java核心学习(二十五) 多线程---线程组和未处理的异常
    java核心学习(二十四) 多线程---线程通信
    java核心学习(二十三) 多线程---线程同步
    java核心学习(二十二) 多线程---线程控制
    模线性方程 poj2115
    求两个圆的重合面积+二分 hdu3264
    求多边形面积 HDU2036
    判断两直线是否相交 hdu1086
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/13201025.html
Copyright © 2011-2022 走看看