图的总结复习

在这里插入图片描述


前言

本文是一篇图的复习总结文章。文首对定义和术语细致罗列,主体部分使用“抓主干,探细微”的方法即将知识点简要回顾,并将每一个知识点的详细复习嵌入超链接,文末对几道疑难问题进行了讨论。希望这一篇有层次有重点的博客能帮大家和我本人复习起来能够事半功倍。

一、定义及基本术语

1.图的定义

G=(V,E),V为顶点集,E为边集。设图有n个顶点,V={v1,v2,v3,…,vn}

2.图的基本术语

有向图<v,w>属于E,表示从弧尾v到弧头w的一条弧。

无向图边(v,w)属于E,

混合图既有有向边,又有无向边的图

简单图简单无向图(不存在顶点到自身的边,且任意两个不同的顶点之间没有平行的两条边),简单有向图(不存在顶点到自身的弧,且任意两个不同的顶点之间没有同方向 的两条弧)。简单无向图和简单有向图统称为简单图。

邻接、依附或关联若无向图有边(v,w),则称顶点v和w相邻或邻接,称(v,w)依附点点v和w,或称与边(v,w)相关联的 两个顶点是v和w;有向图若有弧<v,w>,则称顶点v邻 接到w,w邻接自v,弧<v,w>依附顶点v和w,或称与弧<v,w>相关联的两个顶点是v和w。通常称w是v的邻接点

无向完全图对简单无向图,图中任意两个不同的定点件都有边。有n个顶点的无向完全图有n(n-1)/2条边

有向完全图对简单有向图,任意两个顶点间都有方向互为相反的两条弧。有n个顶点的有向完全图有n(n-1)条弧

网或赋权图无向图或有向图的边或弧上带有一个表示某种物理量的权值

稀疏图、稠密图边或弧数很少(多)的无向图或有向图

顶点的度、入度、出度无向图中任意顶点v,与v相关联的边数称为v的度,Degree(v),间记D(v),有n个顶点和e条边的无向图,所有顶点的度之和是边总数的2倍。有向图 中, 以顶点v为弧尾的弧的数目称为v的出度,OD(v),以v为弧头的的弧的数目称为v的入度,ID(v),D(v)=ID(v)+OD(v)为v的度。有n个顶点e条弧的有 向图,所有顶点的入度之和等于出度之和等于边总数e。

子图G=(V,E),G’=(V’,E’),若V’是V的(真)子集,E’是E的(真)子集,且E’中的边仅与V’中的顶点相关联,则G’是G的(真)子图。

路径、简单路径、回路无(有)向图G=(V,E),若有顶点序列vs=vi1,vi2,vi3,…,vik=vk,且边(vij-1,vij)(弧<vij-1,vij>)属于E,称vs到vk存在路径vi1,vi2,vi3,…,vik。若vs到 vk路 径上顶点除顶点vs和vk可以相同外,其他顶点都不同,上述路径为简单路径。若vs=vk,则称为回路。

连通和可达有向图中顶点v到w有路径称v到w是可达的。无向图v到w有路径称v和w是连通的

连通图和强连通图无向图中任意两个不同顶点都是连通的称它为连通图,否则为非连通图。有向图中任意两个不同顶点都是可达的称之为强连通图或简称连通图,否则为非强 连通图或非连通图

连通分量和强连通分量无向图的极大连通子图称为连通分量有向图的极大强连通子图称为强连通分量或连通分量。极大指该子图包括了所有连通的顶点以及这些顶点相关联的 所有边。

树和有向树连通且无回路的的无向图称为无向树,简称树。含n个顶点的树有n-1条边。在忽略弧方向后,连通且无回路的有向树称为有向树。含n个顶点的有向树有n-1条弧。 实际中指的有向树在选定一个顶点作为根节点后,弧的方向都与从根节点指向叶结点的方向一致或全部相反。

生成树、生成森林由n个顶点构成的连通无向图的任何一个含n个顶点的极小连通子图称为该图的生成树。对于非连通无向图,由连通子图课得到生成子树,非连通无向图的所 有连通分量得到的生成子树构成该树的生成森林

————————————————

二、分类总结

1.无权图

无向图

——搜索

深度优先搜索(深度优先搜索经常被用于游戏仿真中(或者现实世界中与游戏相似的情况)。在一般游戏中,可以在几个可能的动作中选择一个,每个选择导致更进一步的选择,这些选择又产生了更多的选择,这样就形成了一个代表可能性不断延伸的树形图。这就是决策树。)

广度优先搜索 (BFS首先找到与起始点相距一条边的所有顶点,然后是相距两条边的顶点,以此类推。如果要寻找起始顶点与指定顶点的最短距离,那这个属性非常有用。首先执行BFS,当找到指定顶点时,就可以说这条路径是到这个顶点的最短路径。)

——最小生成树

Prim算法(图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。)

Kruskal算法 (它从另一途径求网的最小生成树。其基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止 )

在我看来,这两种算法最大的区别就是前者对点操作而后者对边操作。

有向图

——拓扑排序

造出拓扑序列的实际意义是:如果按照拓扑序列中的顶点次序,在开始每一项活动时,能够保证它的所有前驱活动都已完成,从而使整个工程顺序进行,不会出现冲突的情况。

——有向图的连通性

1.从前面得知,在无向图中,利用深度优先和广度优先搜索可以找到所有相互连通的点。而对有向图来说,就有点麻烦了。因为不能从任意一个顶点开始,期望找到所有其他连通的顶点,因为图是有方向的。关于有向图连通性的问题主要是,如果从一个指定顶点出发,能够到达哪些顶点?
2. 对于有向图的连通性,还有一个问题:一个顶点,是否可以从另外一个顶点可以到达?对于这个问题,可以查看连通性表,但是这需要查看连通性表的某行所有表项,需要O(N)的时间复杂度。能否有一个更好的算法,可以在O(1)时间复杂度里,告知一个顶点对另一个顶点是否可以到达?
很明显,前者使用连通性表可解(连通性表,其实就是一张表,对于这个表上的所有顶点,从这个顶点能到达图中哪个顶点,得到连通性表的方法很简单,就是对每一个顶点使用DFS即可)。
至于后者嘛,则需要使用Warshall算法。事实上,它的本质就是动态规划。

2.带权图

——带权图的最小生成树

带权图的最小生成树同样主要使用Prim算法和Kruskal算法。其实就是找到一棵最小生成树,连接所有顶点,权值最小。要注意,最小生成树也不一定是唯一的。这在现实生活中有很大的意义,例如光纤布线等。要实现这个算法需要使用优先级队列。但这里要注意两个问题
(1)连通n个顶点,需要n-1条边;(2)尽可能选取权值小的边,不能构成回路。
两个算法:
(1)Prim算法
此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。
图的所有顶点集合为;初始令集合;
在两个集合能够组成的边中,选择一条代价最小的边,加入到最小生成树中,并把并入到集合u中。
重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止。
由于不断向集合u中加点,所以最小代价边必须同步更新;需要建立一个辅助数组closedge,用来维护集合v中每个顶点与集合u中最小代价边信息:
在这里插入图片描述
(2)Kruskal算法
此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。

  1. 把图中的所有边按代价从小到大排序;
  2. 把图中的n个顶点看成独立的n棵树组成的森林;
  3. 按权值从小到大选择边,所选的边连接的两个顶点,应属于两颗不同的树(为什么要有这个规定,是因为如果两个顶点属于不同的树,就不会形成环了),则成为最小生成树的一条边,并将这两颗树合并作为一颗树。
  4. 重复(3),直到所有顶点都在一颗树内或者有n-1条边为止。
    在这里插入图片描述
——最短路径

对于带权无向图来说,还有一个很重要的问题:给定两个顶点,如何找到一条路径,令两个顶点之间连通,而且权值最小呢?这里要用到Floyd算法。而如果是带权的有向图,要使用Dijkstra算法。

——AOE网与关键路径

有向图中,用顶点表示活动,用有向边表示活动之间开始的先后顺序,则称这种有向图为AOV网络;AOV网络可以反应任务完成的先后顺序(拓扑排序)。
在AOV网的边上加上权值表示完成该活动所需的时间,则称这样的AOV网为AOE网,如下图:在这里插入图片描述
 图中,顶点表示事件(能被触发,两特征属性:最早发生时间Ve(j);最晚发生时间Vl(j)),边表示活动(能被开始,两特征属性:最早开始时间e(i);最晚开始时间l(i)),权表示活动持续时间,通常用AOE网来估算工程完成的时间

三、疑难问题及解决方案

1.六度空间“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图所示:在这里插入图片描述“六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。
假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。
输入格式:
输入第1行给出两个正整数,分别表示社交网络图的结点数N(1,表示人数)、边数M(≤,表示社交关系数)。随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个结点的编号(节点从1到N编号)。

输出格式:
对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:(空格)百分比%”。

输入样例:
下面展示一些 内联代码片

10 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10

输出样例:

1: 70.00%
2: 80.00%
3: 90.00%
4: 100.00%
5: 100.00%
6: 100.00%
7: 100.00%
8: 90.00%
9: 80.00%
10: 70.00%

解题思路:1.对每个结点使用广度优先搜索距离小于6的结点,并统计个数
2.使用层数(level)来表示距离,其中本结点为第0层,距离1的结点为第1层…
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>

#define MAXVEX 10005

void CreateGraph( );
int BFSTraverse(int i);

int G[MAXVEX][MAXVEX],Nv,Ne;
int visited[MAXVEX];

int main()
{
    int i,j;
    int count;
    double b;
    CreateGraph();
    for( i=1; i<=Nv; i++)
    {
        count = BFSTraverse(i);
        b = 100.0*count/Nv;
        printf("%d: %.2f%%\n",i,b);
    }

    return 0;
}

void CreateGraph()
{
    //用邻接矩阵表示图
    int i,j;
    int v1,v2;
    scanf("%d %d",&Nv,&Ne);
    for( i=0; i<=Nv; i++)
    {
        for( j=0; j<=Nv; j++)
        {
            G[i][j] = 0;  //初始化
        }
    }
    for( i=0; i<Ne; i++)  //注意这里是读入边
    {
        scanf("%d %d",&v1,&v2);
        G[v1][v2] = 1;
        G[v2][v1]= G[v1][v2];  //无向图对称
    }
}

int BFSTraverse( int i)
{
    int q[MAXVEX]= {0}; //用数组表示队列
    int rear=-1,front=-1;
    int j;
    int temp;
    int cnt ;

    int level;   //当前结点所在的层数
    int last;      //该层的最后一个结点
    int tail;    //最后一个进入队列的结点

    for( j=0; j<=Nv; j++)
    {
        visited[j] = 0;
    }

    visited[i] =1;
    cnt = 1;
    level = 0;   //本结点不算在层数里
    last = i;
    q[++rear] = i;  //入队
    while( front<rear )    //判断队列是否为空
    {
        temp =q[++front];  //出队

        for( j=1; j<=Nv; j++)
        {
            if( G[temp][j] && !visited[j])
            {
                visited[j] = 1;
                q[++rear] = j;
                cnt ++;
                tail = j;
            }
        }
        if( temp==last)
        {
            level ++;
            last = tail;
        }
        if( level==6 )
        {
            break;
        }
    }


    return cnt;
}

2.旅游规划
此题难度较高,可移步此博客获得较详细的解析。

7-10 旅游规划

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gyuhow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值