考虑n+1个矩阵的序列M0,M1,……,Mn,将矩阵Mk的第i行记作Mk[i,j].
对于k=0,1,……,n,Mk[i,j]=1当且仅当在R的关系图中存在一条从xi到xj路径,并且这条路径除了端点外中间只经过{x1,x2,……,xk}中的结点。WARSHALL算法从M0开始,顺序计算M1,M2,……,直到Mn为止。
我们知道,对于关系R对应的关系矩阵M来讲,其传递闭包R(t)对应的矩阵MT中,MT[i,j] = 1,当且仅当M[i,j] = 1或M[i,k] = M[k,j] = 1.
算法Warshall
输入:M(R的关系矩阵)
输出:MT(t(R)的关系矩阵)
1.MT <- M
2.for k <- 1 to n do
3. for i <- 1 to n do
4. for j <- 1 to n do
5 MT[i,j] <- MT[i,j] + MT[i,k] * MT[k,j](此处的“+”和“*”都是逻辑加和逻辑乘)
具体代码如下:
#include<stdio.h> int main(void){ //get |A| int n; printf("plz input |A|.\n"); scanf("%d",&n); //input R[n][n] printf("plz input R.\n"); int R[n][n] = {0}; for(int i1 = 0; i1 <= n-1; i1++) for(int j1 = 0; j1 <= n-1; j1++) scanf("%d",&R[i1][j1]); //Warshall for(int i2 = 0; i2 <= n-1; i2++) for(int j2 = 0; j2 <= n-1; j2++) { if(R[j2][i2] != 0) { for(int k = 0; k <= n-1; k++) R[j2][k] |= R[i2][k]; } } //output t(R) printf("t(R):\n"); for(int i3 = 0; i3 <= n-1; i3++) { { for(int j3 = 0; j3 <= n-1; j3++) printf("%d ",R[i3][j3]); } printf("\n"); } }