最小生成树 $Kruskal$ 算法

#include <bits/stdc++.h>
using namespace std;

const int maxn = 5e5 + 10;
int h[maxn], v[maxn], nx[maxn], in[maxn];
int n, m, sz;

void add(int a, int b) {
  v[sz] = b;
  nx[sz] = h[a];
  h[a] = sz;
  in[b] ++;
  sz ++;
}

void init() {
  for(int i = 1; i <= n; i ++) {
    h[i] = -1;
    in[i] = 0;
  }
  sz = 0;
}

void work() {
  queue<int> Q;
  vector<int> ans;
  for(int i = 1; i <= n; i ++) {
    if(in[i] == 0) {
      Q.push(i);
    }
  }
  while(!Q.empty()) {
    int tp = Q.front();
    Q.pop();
    ans.push_back(tp);
    for(int i = h[tp]; i != -1; i = nx[i]) {
      in[v[i]] --;
      if(in[v[i]] == 0) {
        Q.push(v[i]);
      }
    }
  }

  if(ans.size() != n) {
    printf("failed
");
  } else {
    for(int i = 0; i < n; i ++) {
      printf("%d%s", ans[i], i == n - 1 ? "
" : " ");
    }
  }
}

int main() {
  while(~scanf("%d%d", &n, &m)) {
    init();
    for(int i = 1; i <= m; i ++) {
      int a, b;
      scanf("%d%d", &a, &b);
      add(a, b);
    }
    work();
  }
  return 0;
}

 

原文地址:https://www.cnblogs.com/zlrrrr/p/9744391.html