离散数学 用C++实现 求传递闭包
#include<bits/stdc++.h>
using namespace std;
const int maxv= 21;
struct Pair {
//定义 有序对
int x;
int y;
Pair(int ix, int iy) {
x = ix;
y = iy;
}
void print() const{
cout << "<" << x << "," << y << ">";
}
};
//定义关系的排序
typedef struct {
//运用重载定义集合 set 中的有序对排列按照字典顺序
bool operator() (const Pair p1, const Pair p2) const{
if(p1.x!=p2.x) return p1.x<p2.x;
return p1.y<p2.y;
}
}compare;
int main() {
int n;
int case_no = 1;
while (cin >> n) {
//输入元素个数
int m;
cin >> m;
int j,k,i,t;
set<Pair, compare> st;//定义 Pair的集合 compare为排序方式
int a[maxv][maxv]={
0};
for(i=0;i<m;++i){
scanf("%d%d",&j,&k);//将 输入的元素存入二维数组a(组成矩阵)
a[j][k]=1;
st.insert(Pair(j,k)); //将集合 a 存入集合 st
}
int b[maxv][maxv],c[maxv][maxv];
memcpy(b,a,sizeof(a));// b矩阵 copy 成 a矩阵
for(t=1;t<n;++t){
//计算 a的n次方 并依次更新集合st
memcpy(c,a,sizeof(a));//将 c矩阵 copy成 a矩阵 的i次方
for(i=1;i<=n;++i){
for(j=1;j<=n;++j){
for(k=1;k<=n;++k){
a[i][j]+=b[i][k]*c[k][j];
}
}
}//计算 a的次方
for(i=1;i<=n;++i){
for(j=1;j<=n;++j){
if(a[i][j]>0) st.insert(Pair(i,j));
}
}//将 每次计算的结果 (如果大于零 则表明其真值为 1 )存入 集合st 中
}
cout << "case " << case_no++ << ":" << endl;
for(set<Pair, compare>::iterator it=st.begin();it!=st.end();++it){
it->print();
printf("\n"); //由 set会直接删除重复的元素 又自定义了 排序方式 直接输出即可
}
}
return 0;
}
代码已经说的很明白了 就简要说两点
定义
struct Pair {
//定义 有序对
int x;
int y;
Pair(int ix, int iy) {
x = ix;
y = iy;
}
void print() const{
//定义输出方式
cout << "<" << x << "," << y << ">";
}
};
//定义关系的排序
typedef struct {
//运用重载定义集合 set 中的有序对排列按照字典顺序
bool operator() (const Pair p1, const Pair p2) const{
if(p1.x!=p2.x) return p1.x<p2.x;
return p1.y<p2.y;
}//函数重载定义
}compare;
计算闭包的方法
就是得到其矩阵前n次方(就是矩阵乘法)的并集
for(i=1;i<=n;++i){
for(j=1;j<=n;++j){
if(a[i][j]>0) st.insert(Pair(i,j));
}//将每个次方存入进集合中 由于集合会删除重复的元素 且我们自定义了排序方式 最后直接输出即可
最后
wish you all the best.