图论算法基础

news2024/11/18 11:26:24

图论算法基础

  • 有向图
    • 有向图的实现方式
  • 无向图
    • 无向图的实现方式
  • 连通图
    • 连通分量的定义
    • 强连通图和强连通分量的定义
    • 弱连通图和单向连通图的定义
    • 判断图是否是强连通图,弱连通图还是单项连通图
      • 一个很典型的错误代码
      • JAVA实现
      • C++实现
  • 生成树
  • 最小生成树
  • 拓扑排序
    • 邻接表的实现方式
      • 数组模拟邻接表
      • 容器模拟邻接表
    • 拓扑排序面试题

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

有向图

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

有向图的实现方式

在这里插入图片描述
在这里插入图片描述
邻接表实现
在这里插入图片描述
一个例子
在这里插入图片描述

邻接矩阵
在这里插入图片描述

无向图

边没有方向的图称为无向图
在这里插入图片描述

无向图的实现方式

用邻接表和邻接矩阵实现
在这里插入图片描述
在这里插入图片描述
一个例子(去掉所有的箭头)
在这里插入图片描述

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

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

连通图

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

连通分量的定义

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

强连通图和强连通分量的定义

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

在这里插入图片描述

弱连通图和单向连通图的定义

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

其中1不能到4,4也不能到1,所有此图只是弱连通图,不是单向连通图。

单向连通图
在这里插入图片描述
在这里插入图片描述

强连通图必是单向连通图,单向连通图必是弱连通图。(反正未必)

在这里插入图片描述

判断图是否是强连通图,弱连通图还是单项连通图

在这里插入图片描述

解题方法:先判断是否为弱连通图,然后单向连通图,最后判断是不是强连通图(从大范围到小范围的递进)

//
看一下有向图的邻接矩阵表示
在这里插入图片描述 在这里插入图片描述
//强连通图
在这里插入图片描述 在这里插入图片描述
//单向连通图
在这里插入图片描述 在这里插入图片描述
//弱连通图
在这里插入图片描述 在这里插入图片描述

思路很简单,在邻接矩阵中,将间接连通的点连接起来,然后进行判断就行。
从大范围到小范围的缩小判断。。。先判断弱连通,再单向连通,再强连通

一个很典型的错误代码

package graphTheory;

import java.util.Scanner;

public class graphJudgeFalse {

        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入节点数目");
            int n = scanner.nextInt();
            int a[][] =new int[n][n];
            System.out.println("请输入邻接矩阵: ");
            for (int i=0;i<n;i++){
                for (int j =0;j<n;j++){
                    a[i][j] = scanner.nextInt();
                }
            }
//        int[][] a = {{0,1,0,0},{0,0,0,1},{1,0,0,0},{0,0,1,0}};
//        int n =4;
            //将间接连通的节点连通(矩阵对应的位置值赋值为1)
            for (int i=0;i<n;i++){
                for (int k=0;k<n;k++){
                    for (int j=0;j<n;j++){
                        if(a[i][k]!=0&&a[k][j]!=0){
                        a[i][j]=1;
                    }
                }
            }
        }

        //判断图类型
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                if(i!=j&&a[i][j]==0&&a[j][i]==0){
                    //存在互不连通的点
                    System.out.println("该图为弱连通图");
                    return;
                }
            }
        }
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                if(i!=j&&a[i][j]+a[j][i]==1){
                    //存在只通单边的点(单向点)
                    System.out.println("该图为单向通图");
                    return;
                }
            }
        }
        //到这里,说明所有的点都可以双向到达
        System.out.println("该图为强连通图");

    }
}

输入强连通图的邻接矩阵,得到错误的结果

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

原因: 2节点到1节点是连通的,
但是循环赋值的时候a[2][4]!=0 而a[4][ j ]中只有a[4][3]为1所以a[2][3]==1(2和3连通)
就略过了2和1的连通,到了a[3][…]了,导致误判为单向连通图,
并且a[i][j]中i和j相同值的位置也错误的赋值为1
(注意:这里没考虑数组下标为0开始,默认a[1][1]就是对应1,1位置,
实际代码是从0到3)
在这里插入图片描述

JAVA实现

package graphTheory;

import java.util.Scanner;

public class graphJudge {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入节点数目");
        int n = scanner.nextInt();
        int a[][] =new int[n][n];
        System.out.println("请输入邻接矩阵: ");
        for (int i=0;i<n;i++){
            for (int j =0;j<n;j++){
                a[i][j] = scanner.nextInt();
            }
        }
//        int[][] a = {{0,1,0,0},{0,0,0,1},{1,0,0,0},{0,0,1,0}};
//        int n =4;

        //将间接连通的节点连通(矩阵对应的位置值赋值为1)
        for (int i=0;i<n;i++){
            for (int k=0;k<n;k++){
                for (int j=0;j<n;j++){
                    if(a[i][k]!=0&&a[k][j]!=0&&(i!=j)){
                        a[i][j]=1;
                    }
                }
            }
        }
        //第二次循环赋值是为了吧第一次漏掉的点补上来。。。。
        for (int i=0;i<n;i++){
            for (int k=0;k<n;k++){
                for (int j=0;j<n;j++){
                    if(a[i][k]!=0&&a[k][j]!=0&&(i!=j)){
                        a[i][j]=1;
                    }
                }
            }
        }
        //判断图类型
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                if(i!=j&&a[i][j]==0&&a[j][i]==0){
                    //存在互不连通的点
                    System.out.println("该图为弱连通图");
                    return;
                }
            }
        }
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                if(i!=j&&a[i][j]+a[j][i]==1){
                    //存在只通单边的点(单向点)
                    System.out.println("该图为单向通图");
                    return;
                }
            }
        }
        //到这里,说明所有的点都可以双向到达
        System.out.println("该图为强连通图");

    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

C++实现

#include <iostream>

using namespace std;



int main()
{
	system("chcp 65001");
	int n;
	cout<<"输入节点个数";
	cin>>n;

	cout<<"输入邻接矩阵";
	int** a = (int**)malloc(sizeof(int*)*n);
    for(int i=0;i<n;i++)                     
    {
        a[i]=(int*)malloc(sizeof(int)*n);  
    } 

	for(int i = 0;i<n;i++){
		for (int j = 0; j < n; j++)
		{
			cin>>a[i][j];
		}
		
	}
	//将间接连接的点连接
	for(int i = 0;i<n;i++){
		for(int k=0;k<n;k++){
			for(int j=0;j<n;j++){
				if(a[i][k]!=0&&a[k][j]!=0&&(i!=j)){
					a[i][j]=1;
				}
			}
		}
	}
	//第二次循环补漏
	for(int i = 0;i<n;i++){
		for(int k=0;k<n;k++){
			for(int j=0;j<n;j++){
				if(a[i][k]!=0&&a[k][j]!=0&&(i!=j)){
					a[i][j]=1;
				}
			}
		}
	}
	//判断类型
	for (int i=0;i<n;i++){
        for (int j=0;j<n;j++){
            if(i!=j&&a[i][j]==0&&a[j][i]==0){
                    //存在互不连通的点
                std:cout<<"该图为弱连通图";
                return 0;
            }
        }
        }
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                if(i!=j&&a[i][j]+a[j][i]==1){
                    //存在只通单边的点(单向点)
                    cout<<"该图为单向通图";
                    return 0;
                }
            }
        }
        //到这里,说明所有的点都可以双向到达
        cout<<"该图为强连通图";
    
	return 0;
}

在这里插入图片描述

生成树

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

最小生成树

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

稀疏图用邻接表存储,稠密图用邻接矩阵存储

拓扑排序

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

拓扑序列一定是针对有向图
拓扑排序无环
能够拓扑排序的图是:有向无环图
有向图的拓扑排序就是宽度优先搜索的应用

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

如果存在环的话,一定会存在一些点不会入队。因为有的边删不了,所以不可以进行拓扑排序
在这里插入图片描述

邻接表的实现方式

数组模拟邻接表

容器模拟邻接表

拓扑排序面试题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184000.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ShaderGraph】道路引导,小溪流水等UV动画效果

目录 一&#xff1a;创建ShaderGraph文件 二&#xff1a;设置UV动画速度变量 ​三&#xff1a;设置UV动画方向和Tiling变量 ​四&#xff1a;设置贴图属性 五&#xff1a;设置主色MainColor属性 六&#xff1a;最终效果 一&#xff1a;创建ShaderGraph文件 1.在assets下…

css之BFC是什么

在讲BFC之前先来了解一下FC FC-Formatting Context FC全称Formatting Context(格式化上下文)&#xff0c;元素在标准流里面都属于一个FC的 官网解释&#xff1a; Boxes in the normal flow belong to a formatting context,which may be block or inline, but not both sim…

指针(基础)

目录 一、内存和地址 二、指针是什么&#xff1f; 三、指针变量的内容 四、指针类型 五、间接访问操作符 &#xff08;一&#xff09;易混淆 六、野指针 &#xff08;一&#xff09;野指针成因 1. 指针未初始化 2. 指针越界访问 3. 指针指向的空间释放 &…

php xss攻击

文章目录一、什么是xss攻击二、攻击类型三、php相关处理函数1、htmlspecialchars 函数2、htmlentities 函数3、strip_tags 函数一、什么是xss攻击 xss攻击通常指的是通过利用网页开发时留下的漏洞&#xff0c;通过巧妙的方法注入恶意指令代码到网页&#xff0c;使用户加载并执…

make menuconfig分析

在uboot源码顶层目录下&#xff0c;进入scripts/kconfig目录&#xff0c;打开Makefile文件 mconf作为可执行参数,uboot源码顶层目录下的配置文件传递给conf

39_tp6的rce漏洞

tp6的rce漏洞 一、环境搭建 使用docker本地搭建tp6环境 1. 下载镜像 docker pull vulfocus/thinkphp:6.0.122. 端口映射 启动镜像,并将80端口映射到8081端口,防止80端口冲突,运行容器 docker run -it -d -p 8081:80 1fc5d159922e3. 打开网站 默认的网页目录是在public目…

怎么在线识别图片文字?说一个思路

图片中的文字怎么在线识别&#xff1f;很多小伙伴在接收到图片类型的文件时&#xff0c;不知道怎么处理其中记录的信息。打字整理嫌麻烦怕出错的话&#xff0c;可以借助识别软件来处理&#xff0c;下面给大家介绍三种比较好用的工具&#xff0c;希望能解决你的问题。方法一、在…

SAP ADM100-Unit3 系统配置介绍:如何设置配置文件参数

本节将介绍如何改变配置文件参数的值。 1、管理并维护配置文件 如果想去调整配置文件参数,可以使用操作系统特定的编辑器去调整参数。但是,这个过程是有确定风险的,因此用户必须确保这个调整被正确的执行和记录。设置的参数不正确可能导致实例无法启动。因此,SAP系统提供…

JVM学习疑问之——逃逸分析

前言 根据之前安排的jvm学习计划在进行jvm学习&#xff0c;找到了尚硅谷宋红康老师的jvm视频&#xff0c;跟着视频学习、做笔记&#xff0c;学习到了很多&#xff0c;为尚硅谷及宋红康老师点赞。说到这里&#xff0c;虽然我有一键三连&#xff0c;但这么好的视频&#xff0c;我…

(六)redis持久化操作(RDBAOF)

目录 一、RDB&#xff08;Redis DataBase&#xff09; 1、简介 2、持久化流程 3、dump.rdb文件 4、配置文件 5、rdb的备份 6、rdb的恢复 7、优势 8、劣势 二、AOF&#xff08;Append Only File&#xff09; 1、简介 2、持久化流程 3、AOF和RDB同时开启 4、AOF启动…

HTML中引入CSS样式的第三种方式:链入外部样式表文件

<!-- 第三种方式&#xff1a;链入外部样式表文件&#xff0c;这种方式最常用。 就是将样式写到一个独立的xxx.css文件当中&#xff0c;在需要的网页上直接引入这个xxx.css文件就可以了。 语法格式&#xff1a; <head> …

【自学Docker 】Docker port命令

Docker port命令 概述 docker port命令教程 docker port 命令可以用于列出指定的 Docker容器 的端口映射&#xff0c;或者将容器里的端口映射到宿主机。该命令后面的 CONTAINER 可以是容器Id&#xff0c;或者是容器名。 docker port语法 haicoder(www.haicoder.net)# docke…

jsp 校园相册管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 校园相册管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统采用web模式开发&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境 为TOMCAT7.0,Myeclipse8.5开发&#xf…

计算机组成原理 | 第五章:输入输出系统 | 程序中断方式

文章目录&#x1f4da;概述&#x1f407;I/O系统的概述&#x1f407;输入输出系统的组成&#x1f407;I/O设备与主机的联系&#x1f407;I/O设备与主机信息传送的控制方式&#x1f4da;I/O接口&#x1f407;为什么要设置接口❓&#x1f407;接口的功能和组成&#x1f407;接口和…

Pygame的SurfaceImageTime

Surface用来生成一个矩形&#xff0c;Image用来导入外部图片&#xff0c;Time用来暂停时间。 Surface 生成矩形 facepy.Surface((200,200))填充颜色 face.fill(blue) 放入界面 screen.blit(face,(50,50)) Image 导入图片 imgpy.image.load(d:\\图片\\1.jpg) 缩放…

make prerequisite: 根据文件状态自动确定是否重新执行

Basic 先看一个简单的例子&#xff08;引自Makefile Tutorial By Example&#xff09;&#xff1a;当我们对同一个makefile执行两次make命令时&#xff0c;由于第一次运行已经生成了目标文件blah&#xff0c;第二次make会直接输出blah is up to date&#xff0c;而不会重新com…

(四)Redis配置文件redis.conf详解

目录 一、Units单位 二、INCLUDES&#xff08;包含配置&#xff09; 三、NETWORK&#xff08;网络配置&#xff09; 四、GENERAL&#xff08;总则&#xff09; 五、SNAPSHOTTING&#xff08;拍摄快照&#xff09; 六、REPLICATION&#xff08;复制&#xff09; 七、SECU…

【苹果相册日历推位置推送iMessage】需要将真机的udid复制出来在此添加

推荐内容IMESSGAE相关 作者✈️IMEAX推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容3.日历推 *** …

通过伪代码结合理论模拟pc端接入单点登录(Oauth2浙里办)

前言 还记得那是一个惺忪的早晨&#xff0c;带着困意的我正准备去公司上班&#xff0c;坐车坐到一半&#xff0c;钉钉突然袭来一条红色预警信息&#xff0c;公司查出来有个人阳了&#xff0c;好消息&#xff1a;万幸我还在去公司的路上&#xff0c;没有和他有过多的接触&#x…

机器学习中的数学原理——对数似然函数

这个专栏主要是用来分享一下我在 机器学习中的 学习笔记及一些感悟&#xff0c;也希望对你的学习有帮助哦&#xff01;感兴趣的小伙伴欢迎 私信或者评论区留言&#xff01;这一篇就更新一下《 白话机器学习中的数学——对数似然函数》&#xff01; 目录 一、什么是对数似然函数…