#include<iostream>
#include<vector>
#include<list>
#include<iomanip>
#include<algorithm>
using namespace std;
enum{ INF = INT_MAX };
struct Edge{
int from;
int to;
int Wgt;
Edge(int _from, int _to, int _Wgt = INF) :
from(_from), to(_to), Wgt(_Wgt) {}
bool operator <(const Edge & rhs) const {
return Wgt < rhs.Wgt;
}
};
int root(vector<int> & Fr, int vrt) {
while (Fr[vrt] != -1) {
vrt = Fr[vrt];
}
return vrt;
}
bool Kruskal(vector<vector<int> > & G, vector<int> & Fr) {
//init forest.
vector<int>(G.size(), -1).swap(Fr);
//build Edge list;
list<Edge> EL;
for (int i = 0; i < G.size(); ++i) {
for (int j = 0; j < G.size(); ++j) {
if (G[i][j] != INF && G[i][j] != 0)
EL.push_back(Edge(i, j, G[i][j]));
}
}
EL.sort(); //ascending order.
//span
int Ecnt = 0;
while (Ecnt < G.size() - 1 && !EL.empty()) {
//extract edge.
Edge e(EL.front());
EL.pop_front();
if (root(Fr, e.from) != root(Fr, e.to)) {
++Ecnt; //append edge.
Fr[e.to] = e.from; //merge tree.
}
}
if (Ecnt < G.size() - 1) {
cout << "Not connected graph." << endl;
return false;
}
else
return true;
}
int main(void) {
cout << "Kruskal algorithm." << endl;
int n, m;
while (cin >> n >> m) {
vector<vector<int> > G(n, vector<int>(n, INF));
for (int i = 0; i < n; ++i) G[i][i] = 0;
//input edges.
for (int i = 0; i < m; ++i) {
int s, t;
cin >> s >> t;
cin >> G[s][t];
}
//display matrix.
cout << "Adj: " << endl;
for (int i = 0; i < G.size(); ++i) {
for (int j = 0; j < G.size(); ++j) {
cout << " " << setw(3) << G[i][j];
}
cout << endl;
}
cout << endl;
vector<int> Fr;
if (Kruskal(G, Fr)) {
cout << "Parenthoods of the spanning tree:" << endl;
for (int i = 0; i < Fr.size(); ++i) {
cout << "Vertex: " << i << " Parent: " << Fr[i] << endl;
}
}
}
system("pause");
return 0;
}
很直觀的算法,關鍵在於森林的構造.
輸入樣例:
8 32
0 1 10
1 0 10
0 3 10
3 0 10
0 5 14
5 0 14
0 7 11
7 0 11
1 2 10
2 1 10
1 4 7
4 1 7
1 6 7
6 1 7
2 3 11
3 2 11
2 5 9
5 2 9
2 7 8
7 2 8
3 4 12
4 3 12
3 6 15
6 3 15
4 5 13
5 4 13
4 7 16
7 4 16
5 6 13
6 5 13
6 7 12
7 6 12