传递闭包
传递闭包


思路:
Warshall算法求传递闭包
-
用原始二元关系\(R[i][j]\)给\(T[i][j]\)赋初值
-
类似Floyd-Warshall算法,三层循环
用外层k,更新 \(i->j\)
这里的更新指的是:假如\(T[i][k]=1\)且\(T[k][j]=1\),则\(T[i][j]\)应该被赋为1
形象的说:i,j通过k“粘”了起来(i->k,k->j,去掉连接点k,i->j直接相连)
优点:
避免了使用\(t(R)=R∪R^2∪R^3∪...∪R^n\),即\(M_t=M+M^2+M^3+...+M^n\),时间复杂度较高的方法
int n,a[N][N],b[N][N];
void warshall()//传递闭包 t(R)
{
for(int k=1;k<=n;++k){
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(b[i][k]==1&&b[k][j]==1)
b[i][j]=1;
}
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
cin>>a[i][j];
b[i][j]=a[i][j];
}
}
warshall();
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
cout<<b[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}
自反闭包和对称闭包:
void getr()//新增:自反闭包 r(R)
{
for(int i=1;i<=n;++i){//加环
b[i][i]=1;
}
}
void gets()//新增:对称闭包 s(R)
{
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){//如果有单向边 加一条反向的边
if(b[i][j]==1)
b[j][i]=1;
}
}
}

浙公网安备 33010602011771号