图论讲解(1)——图基础

前面一直在哔哔数论,是不是感觉很烦的慌了??

╮(╯▽╰)╭唉,你不烦得慌我都烦得慌了!

既然这样,那我们就改个话题,今天我们就讲讲图论。

有的同学就要问图又是个什么鬼?

难道是这个吗?                                          还是这个???

哎呀,身为c++选手,我们肯定说的不是这些东西了对吧!

我们信息学上所说的图是指一个有序的二元组(V,E),V是顶点的集合,E是边的集合,E中的每一个元素都用一个二元组(x,y)来表示,其中x,y∈v。

这么说是不是有点太枯燥?

好,那我们下面来看一个我们所说的图。

有人又要说了:这是什么鬼,那么丑,这是个什么图?!

呵呵,很不幸,我们以后说的图都是这个那么恶心的东西。

one。图的相关概念:

有向图:图当中所有的边都是有向的,比如说:就表示1可以直接连接到达2,但2并不能直接到达1,除非有另一条边2——>1.

无向图:图当中的所有便都是无向的,也就是说如果v1可以到达v2的话,那么v2也一定能到达v1。

连通图:无向图中的两个点都是能相互到达的。

对于这个图来说他是个无向连通图。

这是个有向图。

自环:存在从一个点指向其自身的边称为一个自环。比如说存在一条边1——>1,那么这个图中存在自环。

重边:如果存在两条不同的边连接两个相同的节点(如果是有向图就要求起点相同,终点相同),那么这个图中就存在重边。

简单图:指不含有自环和重边的图。

无权图:图中的边没有权值。(如果指长度的话,则可以理解成权值均为1)

有权图:图中的边有权值。

这就是个无权图。

而这是个有权图。

图的基本概念都明白了吧,那么,接下来,我们考虑如何存储一个图。

对于存储图,我们有两种常用的方法:

1.邻接矩阵;

2.邻接链表;

假设给出点数N,边数M,点的编号从1到N,每条边用(a,b)表示从点a到点b的有向边。

我们可以建一个N*N的二维数组,然后这个二维数组当中的元素Aij表示点i到点j是否有边,如果有边则记为1,没有边则记为0.

我们可以把以同一节点为起点的边通过一个链表联系起来。

也就是说,我们可以通过在每一个节点记录一个head[i]表示节点i对应的链表里面的头指针(“第一条边”),

然后在每一条边的信息当中我们记录next[j]表示这条边在链表当中所指的下一条边。

总的来说,图的存储结构主要是两种:

邻接矩阵

邻接链表

而对于两种存储方法的选择,则主要根据图的特点(稠密图还是稀疏图)来选择

当然在数据规模小的时候,采用邻接矩阵要更为简洁

还要看代码吗??

好吧。

邻接矩阵:

#include<stdio.h>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10000
using namespace std;
int e[N][N],vis[N];
int n,m,a,b,c;
void bfs(int x)
{
    vis[x]=1;
    for(int i=1;i<=n;i++)
    {
        if(e[x][i]&&!vis[i])
         bfs(i);
    }
}
int main()
{
    scanf("%d%d",&n,&m);//n个点,m条边
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        e[a][b]=c;//有向边
    }
    bfs(1);
    return 0;
}

邻接表:

#include<vector>
#include<cstdlib>
#include<cstring>
#include<stdio.h>
#include<iostream>
#include<algorithm>
#define N 100000
#define maxn 123456
using namespace std;
int m,n,x,y,z;
bool vis[N];
vector<pair<int,int> >vec[N];
void bfs(int x)
{
    vis[x]=1;
    for(int i=0;i<vec[x].size();i++)
    {
        if(!vis[vec[x][i].first])
          bfs(vec[x][i].first);
    }
 }
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        vec[x].push_back(make_pair(y,z));
    }
    bfs(1);
    return 0;
 }
时间: 2024-09-30 10:33:36

图论讲解(1)——图基础的相关文章

图论及其应用——图

我们探索某个领域的知识,无不怀揣的核弹级的好奇心与求知欲,那么,今天,我们就将开始对图论的探索.   观察一副<机械迷城> 的一处谜题.    不得不承认,<机械迷城>这款解密游戏难度远胜于<纪念碑谷>, 其中一个困难点就在于——<纪念碑谷>的目标是很明确的,但是<机械迷城>往往需要自己凭感觉设立目标.而这里的关卡的目标,就是堵住第三个出水口. 为了解决这个谜题,如果不去考虑用暴力枚举的方法去试探(其实很多情况下都是用到这种情况)一开始,我们似乎

图论算法 有图有代码 万字总结 向前辈致敬

图的定义 背景知识 看到这篇博客相信一开始映入读者眼帘的就是下面这幅图了,这就是传说中的七桥问题(哥尼斯堡桥问题).在哥尼斯堡,普雷格尔河环绕着奈佛夫岛(图中的A岛).这条河将陆地分成了下面4个区域,该处还有着7座连接这些陆地的桥梁. 问题是如何从某地出发,依次沿着各个桥,必须经过每座桥且每座桥只能经过1次,最终回到原地. 不知道这个问题且好奇的童鞋现在肯定在忙活着找出来这道题的结果了. 是伟大的数学家欧拉(Leonhard Euler)在1736年首次使用图的方法解决了该问题. 欧拉将上面的模

如何看K线图基础知识

在日K线图中一般白线.黄线.紫线.绿线依次分别表示:5.10.20.60日移动平均线,但这并不是固定的,会根据设置的不同而不同,比如你也可以在系统里把它们设为5.15.30.60均线. 你看K线图的上方有黄色PMA5=几的字样,就是五日均线等于几的意思.其他的有紫色的10日均线PMA10=什么的.设定的话双击数字就行!数字是几就是几日均线,颜色和线的颜色一样! 那是移动平均线,在日K线图中一般白线.黄线.紫线.绿线依次分别表示:5.10.20.60日移动平均线,但这并不是固定的,会根据设置的不同

《大话设计模式》笔记-基础知识1:UML类图基础知识

好多计算机技术书籍或者文章中常用到UML类图,本书作者介绍每一种设计模式就是用类图+面向对象语言小程序(用的C#,其基础知识另文介绍)+人物对话解释知识点.本文就是介绍<大话设计模式>中所用到UML类图的基础知识. 上图是一个整体的图,特别要注意各种样式的箭头,下文分别用局部小图说明各知识点. 类 类图分三层: (1)      类名称,如果是抽象类就用斜体标识.本例,类名称是"动物",且其是一个抽象类. (2)      类特性,通常是字段和属性.本例,类特性是"

UML图基础知识

一.UML简述 类是面向对象系统中最重要的构造块.类图显示了一组类.接口.协作以及他们之间的关系,通过类图,我们能够很好的掌握类与类之间的关系. 首先给出一幅UML类图,此图来源于<大话设计模式>,其中讲的很好,感兴趣的可以去查看.然后细细查看图中的每个符号.每个元素,思考之间的关系. 二.UML类图中包括常用的六种关系以及各自的表示形式 从上图中我们可以很明显的发现六种关系及各自如何表示, 1. 空心三角形+实线:继承关系 2. 空心三角形+虚线:实现接口 3. 空心菱形+实线箭头:聚合关系

图 -- 基础

图 图可以分为有向图(directed graph)和无向图(undirected graph). 每个顶点都临界的无向图为完全图(complete graph).如果无向图G的顶点集V可以划分为V1,V2,是的对(u,v)属于E有u属于V1,v属于V2,则称图为二分图(bipartite graph). 无回路的无向图成为森林:连通的,无回路的无向图为(自由)树,也叫做有向无环图(dag). 有n(n-1)/2条边的无向图称为完全图(complete graph). 具有n(n-1)条弧的有向

图论讲解(3)——最小生成树

关于这个东西,有的童鞋又要开始蒙了,最小生成树是个什么鬼?! 前面我们已经说过树是什么东西了,所谓最小生成树嘛,最小嘛,那就是所有生成的树中最小的那个呗! 太别扭了对吧? 好,我们来看看官方回答. 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出. prim算法 Prim算法是通过先选取一个点,然后不断加入点的一个过程. ’初始化:V’={x},E’={

图论6——仙人掌图

如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌 图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路. 输入的第一行包括两个整数n和m(1≤n≤50000以及0≤m≤10000).其中n代表顶点个数,我们约定图中的顶点将从1到n编号.接下来一共有m行.代表m条路径.每行的开始有一个整数k(2≤k≤1000),代表在这条路径上的顶点个数.接下来是k个1到n之间的整数,分别对应了一个顶点,相邻的顶点表示存在一条连接这两

MFC对话框贴图基础上控件Stasic变成透明的

相应WM_CTLCOLOR函数 添加以下代码: HBRUSH CMFCApplication2Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { ..... switch (pWnd->GetDlgCtrlID()) { case IDC_STATIC: { pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0, 0, 0)); return (HBRUSH)GetStockO