图论基础1

一图(dp)

我们已经学过一些简单的数据结构,例如线性表和二叉树。现在,需要学习一种新的数据结构——图。虽然相比于前面讲过的数据结构,图会复杂一些,但是依然能用很多生活中存在的例子来解释图这种数据结构。

比如,现在新同学站在校园的正门口,手里拿着校园地图。可以从地图上看到有很多建筑物。复杂的路网四通八达,连接着这些建筑物。如果希望偷个懒,走最近的道路到达目的地,或者是希望制定一种方案,参观完学校内的每一种建筑物,都可以使用“图”这一数据结构来模拟。通过建模,编写计算机程序,就可以解决这类问题。

基本思想是:

设无向连通网为G=(V,E),令G 的最小生成树为T,其初态为T=(V,{}),即开始时,最小生成树T 由图G 中的n 个顶点构成,顶点之间没有一条边,这样T 中各顶点各自构成一个连通分量。

在E中选择代价最小的边,若该边依附的顶点落在T中不同的连通分量,则将此边加入到T中,否则舍弃此边而选择下一条边(若该边依附的两个顶点属于同一个连通分量,则舍去此边,以免造成回路)。依此类推,当T 中的连通分量个数为1 时,此连通分量便为G 的一棵最小生成树。

dp一般用于解决多阶段决策问题,即每个阶段都要做一个决策,全部的决策是一个决策序列,要你求一个

最好的决策序列使得这个问题有最优解

将待求解的问题分为若干个相互联系的子问题,只在第一次遇到的时候求解,然后将这个子问题的答案保存

下来,下次又遇到的时候直接拿过来用即可

dp和分治的不同之处在于分治分解而成的子问题必须没有联系(有联系的话就包含大量重复的子问题,那

么这个问题就不适宜分治,虽然分治也能解决,但是时间复杂度太大,不划算),所以用dp的问题和用分

治的问题的根本区别在于分解成的子问题之间有没有联系,这些子问题有没有重叠,即有没有重复子问题

dp和贪心的不同之处在于每一次的贪心都是做出不可撤回的决策(即每次局部最优),而在dp中还有考察

每个最优决策子序列中是否包含最优决策子序列,即是否具有最优子结构性质,贪心中每一步都只顾眼前

最优,并且当前的选择是不会依赖以前的选择的,而dp,在选择的时候是从以前求出的若干个与本步骤

相关的子问题中选最优的那个,加上这一步的值来构成这一步那个子问题的最优解

二、图的定义

图(graph)

在这里插入图片描述

如上图是一个图G,一个图由顶点(vertex)集V和边(edge)集E组成,即G=(V, E),和树类似,其顶点又称为结点,并且边是有意义的,如上图(0,1)称为一条边。

上图中黑色的带数字的点就是顶点,可抽象成某个事物或对象。顶点之间的线就是边,表示事物与事物之间的关系。需要注意的是在图论中边表示的是顶点之间的逻辑关系,粗细长短都无所谓的。包括上面的顶点也一样,表示逻辑事物或对象,画的时候大小形状都无所谓。

顶点(vertex)的属性:

度数(degree),与该顶点相关联的总边数,一个图G的总度数d(V)等于总边数2倍:2E。当图的边具有方向时,一个顶点又分为出度(out-degree)和入度(in-degree),出度是以该顶点为起点的边数,入度是以该顶点为终点的边数。

阶数(order),图G中顶点集V的大小为G的阶数。

边又称为线(line)或弧(arc),边(u,v)中表示u和v邻接(adjacent),(u, v) ∈ E,边(edge)的属性:

有向边: 有向边就是固定这一条边只能从x通往y,y通往x则不可以。无向边 : 无向边就是一条边可以从x通往y,y也可以通往x。自环边: 一条边的起点终点是一个点。平行边: 两个顶点之间存在多条边相连接

三、图的储存

那么,该怎么去储存图呢?

1.邻接矩阵

邻接矩阵是二维数据 :例如,g[ ][ ] 时空间需求为V^2,这种存储方式适合存储稠密图

邻接矩阵每一位存的是一条边 行代表的是起始点 ,列代表的是终止点,而里面存的值就是这条边的权值一个点到自己的距离是0,到没有直接边连接的点的权值是无穷大

需要注意的是,有向图与无向图的矩阵不同,对于无向图,当vi、vj之间由边,则a[i][j]=a[j][i]=1,但是有向图,若i指向j,只有a[i][j]=1,a[j][i]=0

邻接矩阵要初始化

for(int i = 1; i <= n1; i++)// n1 为数组第一维大小
    {
        for(int j =  1; j <= n2; j++)// n2 为数组第一维大小
        {
           g[i][j] = g[j][i] =  0 ;
        }
    }
cin>>n>>m;//n表示点的数量,m表示边的数量
 
for(int i = 1;i <= m; i++){//枚举输入边
    cin>>x>>y>>z;//如上描述
 
    dis[x][y] = z;    //有向边:
 
    dis[x][y] = dis[y][x] = z;    //无向边:
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值