O(n^3)的高效闭包算法
算法内容:1.做出关系R的矩阵M
2.枚举每一列,以这一列对应的元素为中间元素去创造新的关系(一行一行来做,如果当前行对应的元素与列对应的元素有关系,例如aRb,则考虑<b,…>有无关系,若有关系则aR…,具体实现就是M[a][…] |= M[b]…
有点类似于多源最短路算法,也是一种动态规划的思想,假设当前枚举到i列,此时矩阵就是只借助前i个点进行扩展,这时候矩阵的结果已经是站在借助前i-1个节点扩展过的结果了,所以此时扩展得来的关系未必只借助了i点,可能还借助了1-i-1的若干点,而这也就是这个算法的巧妙之处所在。
另外,Wallshall算法在离散数学中还是比较重要的,偏序关系的哈斯图cover关系的求解以及可达矩阵的求解都用到了Wallshall算法。
代码实现:
# include <iostream>
# include <map>
using namespace std;
const int MAX_N = 100;
bool Matrix[MAX_N][MAX_N];
int n;
map<char, int> ma_1;
map<int, char> ma_2;
int main() {
cout << "输入集合中的元素个数:\n";
cin >> n;
cout << "输入集合中各元素:\n";
for (int i = 0; i < n; i++) {
char c;
cin >> c;
ma_1[c] = i;
ma_2[i] = c;
}
cout << "输入各关系:\n";
char a, b;
while (cin >> a >> b)
Matrix[ma_1[a]][ma_1[b]] = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (Matrix[j][i]) {
for (int k = 0; k < n; k++) {
Matrix[j][k] |= Matrix[i][k];
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (Matrix[i][j]) {
cout << "<" << ma_2[i] << "," << ma_2[j] << ">\n";
}
}
}
system("pause");
return 0;
}