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

来源:互联网 发布:smc选型软件下载 编辑:程序博客网 时间:2024/05/08 16:06

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

 

 

 

 

代码思路:

 

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 <cstdio>#include <cstring>#include <algorithm>#define MAX 100using 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;} 


 

0 0