link
referenct to @617280219
- Sort and group edges by weight. In each step we process one group of edges
- Discard the edges whose ends are already connected
- Run Tarjan's bridge finding algorithm on each connnected part of the subgraph. Add bridges to critical and the rest to pseudo-critical
- 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;
}
};