离散数学实践三判别图的连通性【JAVA实现】

致歉

  • 由于时间仓促,之前最初的蛋的代码内容有一些小问题,现已修改!

思路

  • 对于给定的邻接矩阵 A,可以用可达矩阵 Warshall 算法求出 A 所表示的图的可达矩阵 P。
    • 对于可达矩阵 P 来说,如果 P 的所有元素均为 1 1 1,则所给的有向图是强连通的;
    • 对于 P 的所有元素(除主对角线元素外) P i j P_{ij} Pij 来说,均有: P i j + P i j > 0 P_{ij}+P_{ij}>0 Pij+Pij>0,则所给有向图是单向连通的。
    • 当所给有向图既不是强连通的,又不是单向连通的时候,我们改造邻接矩阵为:对于矩阵 A 中所有的元素(除主对角线的元素外) a i j a_{ij} aij,若 a i j = 1 a_{ij}=1 aij=1 a j i = 1 a_{ji}=1 aji=1,则 a i j = a j i = 1 a_{ij}=a_{ji}=1 aij=aji=1
    • 对于这样改造之后所得到的新的矩阵 A ′ A' A A ′ A' A相当于原有向图忽略方向之后所得到的无向图的邻接矩阵),再用方法进行判断,当 P ′ P' P的所有元素(除主对角线的元素外)均为 1 1 1时,原有向图是弱连通图;
    • 否则,原有向图是不连通的。

重要算法&Warshall 算法

在这里插入图片描述

  • 认真看图,认真体会

错误避坑

在这里插入图片描述

代码

public static void warshall(int[][] matrix) {
    int cols=0,rows=0,i=0;
    for(cols=0;cols<matrix.length;cols++) {
        for(rows=0;rows<matrix.length;rows++) {
            if(matrix[rows][cols]==1) {
                for(i=0;i<matrix.length;i++) {
                    matrix[rows][i]=matrix[rows][i] | matrix[cols][i];
                }
            }
        }
    }
}

全部代码

package 离散数学;

import java.util.Scanner;

/**
 * @author 缘友一世
 * date 2022/12/30-15:53
 */
public class demo03 {
    public static void main(String[] args) {
        int nums=0;
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入结点的个数:");
        if(scanner.hasNextInt()) {
            nums=scanner.nextInt();
        }
        int[][] matrix=new int[nums][nums];
        int[][] matrix2=new int[nums][nums];
        System.out.println("请输入"+nums+"阶矩阵的值[以空格隔开]:");
        for(int i=0;i<matrix.length;i++) {
            for(int j=0;j<matrix[i].length;j++) {
                if(scanner.hasNextInt()) {
                    matrix2[i][j]=matrix[i][j]= scanner.nextInt();
                }
            }
        }
        warshall(matrix);
        System.out.println("可达矩阵为:");
        display(matrix);
        int res = estimate(matrix);
        if(res==1) {
            System.out.println("该图为强连通图!");
        }else if(res==0) {
            System.out.println("该图为单向连通图!");
        }else if(res==-1){
            transform(matrix2);
            System.out.println("原邻接矩阵改造后为:");
            display(matrix2);
            warshall(matrix2);
            res=estimate02(matrix2);
            if(res==1) {
                System.out.println("原有向图是弱连通的!");
            }else {
                System.out.println("原有向图是非连通的!");
            }
        }
    }
    public static void warshall(int[][] matrix) {
        int cols=0,rows=0,i=0;
        for(cols=0;cols<matrix.length;cols++) {
            for(rows=0;rows<matrix.length;rows++) {
                if(matrix[rows][cols]==1) {
                    for(i=0;i<matrix.length;i++) {
                        matrix[rows][i]=matrix[rows][i] | matrix[cols][i];
                    }
                }
            }
        }
    }
    public static void display(int[][] matrix) {
        for(int i=0;i<matrix.length;i++) {
            for(int j=0;j<matrix.length;j++) {
                System.out.print(matrix[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static int estimate(int[][] matrix) {
        int flag=1;
        for(int i=0;i<matrix.length;i++) {
            for(int j=0;j<matrix.length;j++) {
                if(matrix[i][j]!=1) {
                    flag=-1;
                }
            }
        }
        //标志未改变,所以为强连通图
        if(flag==1) {
            return flag;
        }
        flag=0;//标记为单向连通
        for(int i=0;i<matrix.length;i++) {
            for(int j=0;j<matrix.length;j++) {
                if(i!=j && !(matrix[i][j]+matrix[j][i]>0)) {
                    flag=-1;
                }
            }
        }
        //单向连通图
        if(flag==0) {
            return flag;
        }
        //否则为弱连通
        return flag;
    }
    public static int estimate02(int[][] matrix) {
        int flag=1;
        for(int i=0;i<matrix.length;i++) {
            for(int j=0;j<matrix.length;j++) {
                if(i!=j && matrix[i][j]!=1) {
                    flag=-1;
                    return flag;
                }
            }
        }
        return flag;
    }
    public static void transform(int[][] matrix) {
        for(int i=0;i<matrix.length;i++) {
            for(int j=0;j<matrix.length;j++) {
                if(i!=j && (matrix[i][j]==1 || matrix[j][i]==1)){
                    matrix[i][j]=matrix[j][i]=1;
                }
            }
        }
    }
}

效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值