War-shall 算法 【求传递闭包】 离散数学记录

学离散数学时遇到到第一个算法,记录一下:

 

 

 

 

代码思路:

 

warshall(A[1...n,1...n]
r(0)<-A;
for(k=1;k<=n;k++)
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            r(k)[i,j]=r(k-1)[i,j] or(r(k-1)[i,k] and r(k-1)[k,j]);
return r(n);


 

 

War-shall 算法c++代码实现:

 

#include 
#include 
#include 
#define MAX 100
using namespace std;
int map[MAX][MAX];//输入的矩阵 
int convert[MAX][MAX];//变换后的矩阵 
int mark[MAX][MAX];//标记变换位置 
int sum;//记录变换总位置数 
int n;//n 乘 n矩阵 
void getmap()
{
    printf("输入邻接矩阵:\n");
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            scanf("%d", &map[i][j]);
            convert[i][j] = map[i][j];
            mark[i][j] = 0;
        }
    }
    sum = 0; 
    printf("\n"); 
}
void warshall()
{
    int k, i, j;
    for(k = 1; k <= n; k++)//对当前行的每一个元素 
    {
        for(i = 1; i <= n; i++)//遍历
        {
            for(j = 1; j <= n; j++)//遍历每一行 
            {
                convert[i][j] = (convert[i][j] || convert[i][k]&convert[k][j]); 
            } 
        }
    }
    printf("变换后邻接矩阵:\n");
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            if(j > 1) printf(" "); 
            printf("%d", convert[i][j]);
            if(convert[i][j] != map[i][j])
            sum++, mark[i][j] = 1;
        }
        printf("\n"); 
    }
    printf("\n");
    printf("变换数有%d个\n", sum);
    if(sum)
    printf("变换位置如下:\n");
    else
    return ; 
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            if(mark[i][j])
            printf("位置(%d, %d)由%d -> %d\n", i, j, map[i][j], convert[i][j]);
        }
    }
    printf("\n");
}
int main()
{
    while(printf("顶点个数: "), scanf("%d", &n), n)
    {
        getmap();
        warshall();
    } 
    return 0;
} 


 

你可能感兴趣的:(算法与有趣代码--记录)