图论(入门版)

news/2024/11/29 8:39:04/

目录

1  向、权

 2  最小生成树

2.1  Prim算法

2.2  Kruskal算法

3  最大流问题

3.1  Naive算法

3.2  Ford—Fulkerson算法

3.3  Edmonds—Karp算法

3.4  Dinic算法

4  最小割问题

5  二部图

5.1  判断是否是二部图的方法

5.2  匈牙利算法(最小匹配问题)

5.3  最大匹配问题

5.4  婚配问题


1  向、权

向:一点和另一点之间有单向和双向两种情况

如果A与B间是双箭头或一条无向线相连,代表无向,即可以从A走向B,也可以从B走向A

权:从一点到另一点的代价

如果任何点之间的代价相同,代表无权,反之,则有权

所以,可以分为四类图:无向无权图、无向有权图、有向无权图、有向有权图

对于无权图,可以运用队列+搜索思想,把起点压入队列,然后把起点弹出队列,同时找到能直接到达的结点并压入队列,循环多次直到队列为空时结束循环,可以把所有结点都遍历一遍。

对于有权图,运用优先队列+搜索思想,和上面操作等同,但要同时记录权。

下图是有向无权图:

 2  最小生成树

图和树最大的区别是树一定不能有回路,图没有要求,所以说树是特殊的图

2.1  Prim算法

思路:找已搜索过的点和未搜索过的点之间的最小通路

1:随机找一个起点

2:搜索出所有的和起点连通的路

3:找出代价最小的一条路并连接,这个点和起点在一棵树上

4:按照前面的步骤进行循环,直到所有的点都在一棵树上

判断是否在一棵树上用并查集:

#include <iostream>
using namespace std;int n,m,p;
const int N=5e3+10;
int fa[N];int init()
{for(int i=0;i<N;i++){fa[i]=i;}
}int find(int x)
{int t=x;while(t!=fa[t]){t=fa[t];}while(x!=fa[x]){int temp=fa[x];fa[x]=t;x=temp;}
}void merge(int a,int b)
{a=find(a);b=find(b);if(a!=b){fa[b]=a;//结合到一起,也可以是fa[a]=b;}
}int main()
{cin>>n>>m>>p;init();//初始化父节点; int u,v;while(m--){cin>>u>>v;merge(u,v);}while(p--){cin>>u>>v;u=find(u);v=find(v);puts(u==v?"Yes":"No");}
}

2.2  Kruskal算法

直接把所有路的代价按照从小到大排序,并按此顺序连接结点,注意在连接结点前要判断两结点是否已经在一棵树内,若在一棵树内,则直接跳过。

3  最大流问题

对于一张建设好的网络(流网络)(各边上的数值表示流的容量限制,箭头表示流动方向,该网络的建设好后不允许更改):

考察其最大流是指从源点提供流(假设提供能力总是充足的)
那么管道中的流从s->t的过程中所能达到的最大值是多少? 

3.1  Naive算法

这种算法不是好的算法,对于一些情况来说不能算出最好结果,但这种算法为后面的好的算法提供思路。

找简单路(不绕圈的路,即所有路过的结点不重复,随便找一条符合条件的就行)和简单路中的最小权重,所以这段水流=这条最小路的权重,然后把消耗值减掉,再把权重为0的边去掉,如果起点和终点已经不在一棵树内,则停止循环。这里计算出的“最大流”成为阻塞流

3.2  Ford—Fulkerson算法

这种算法比Naive算法多出的一条是,消耗值要反向加回到图中,而不是简单的减去就结束了

3.3  Edmonds—Karp算法

这种算法比Ford—Fulkerson算法多出的一条是,找简单路时要找最短路径

3.4  Dinic算法

思路:

1:画一张阶梯图(要求路只能连接不同层之间的结点),并计算阻塞流(Naive算法)

2:把Naive算法中算出的所有路的消耗值反向加回到原图中

3:根据2得到的图画阶梯图,然后进入步骤1(来回循环),当找不到阻塞流时结束循环

4  最小割问题

选取某些路并割去,使得没有一条路能从起点走到终点,割去路的加和最小值=最小割

结论:最大流=最小割

5  二部图

5.1  判断是否是二部图的方法

1:随意找一个点染成红色

2:把红色结点的邻接结点染成蓝色

3:把蓝色结点的邻接结点染成红色

4:如此往复,如果此过程没有出现矛盾,则是二部图

5.2  匈牙利算法(最小匹配问题)

这里假设有两个集合U和V,每个集合有三个元素u1、u2、u3、v1、v2、v3。

画一张表格:

u1u2u3
v18910
v2739
v3562

减去每行最小值和每列最小值:

u1u2u3
v10(-8)1(-8)2(-8)
v24(-3)0(-3)6(-3)
v33(-2)4(-2)0(-2)

使得每一行每一列都出现至少一个0。然后对0相应的元素的原始值进行处理即可。

图形思路:

 色块和白块分别有4个,如何才能使匹配量最多?

 M1可以和NA直接匹配

M2发现此时NA已经被匹配了,把M1和NA强行分开,M1此时就找NC匹配

  M3找NB匹配,但这样的话M4就不能匹配了,所以M3只能和ND匹配,这样M4也能匹配

5.3  最大匹配问题

把原始数据变成相反数,变成最小匹配问题即可。

5.4  婚配问题


http://www.ppmy.cn/news/19271.html

相关文章

Docker基本操作

Docker基本操作一、镜像操作1.镜像名称2.镜像命令&#xff08;1&#xff09;拉取、查看镜像&#xff08;2&#xff09;保存、导入镜像二、容器操作1.容器相关命令2.创建并运行一个容器3.进入容器&#xff0c;修改文件4.小结三、数据卷&#xff08;容器数据管理&#xff09;1.什…

基于自适应适应度-距离平衡的随机分形搜索算法(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 ​​​​​​​ &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容…

【代码随想录】Day31~Day37回溯算法

理论基础本质选择每一阶段的局部最优解&#xff0c;达到全局最优。如果找到局部最优然后退出整体最优&#xff0c;就是贪心。一般步骤将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解简单题目分发饼干&#xff1a;力扣455局部…

nginx一网打尽

一、性能怪兽-Nginx概念深入浅出 二、Nginx环境搭建 三、Nginx反向代理-负载均衡 四、Nginx动静分离 五、Nginx资源压缩 六、Nginx缓冲区 七、Nginx缓存机制 八、Nginx实现IP黑白名单 九、Nginx跨域配置 十、Nginx防盗链设计 十一、Nginx大文件传输配置 十二、Nginx配置SLL证书…

【JavaSE】一文看懂构造器/构造方法(Cunstructor)

&#x1f331;博主简介&#xff1a;大一计科生&#xff0c;努力学习Java中!热爱写博客~预备程序媛 &#x1f4dc;所属专栏&#xff1a;Java冒险记【从小白到大佬之路】 ✈往期博文回顾: 【JavaSE】保姆级教程|1万字10张图学会类与对象–建议收藏 &#x1f575;️‍♂️近期目标…

第九层(1):初识STL

文章目录前情回顾初识STLSTL的诞生STL的基本概念STL六大组件STL中的容器、算法、迭代器容器算法迭代器容器、算法、迭代器的配合使用vector中的嵌套使用石碑倒下...后面还有石碑&#xff1f;本章知识点&#xff08;图片形式&#xff09;&#x1f389;welcome&#x1f389; ✒️…

Shell语法

一、概念 Shell 是命令行与操作系统沟通的桥梁&#xff0c;也是一门语言。 Shell 脚本可以直接在命令行中执行&#xff0c;也可以作为文件方便复用。 Linux中常见的 Shell 脚本有&#xff1a; Bourne Shell(/usr/bin/sh或/bin/sh)Bourne Again Shell(/bin/bash)C Shell(/us…

【计组笔记01】计算机组成原理之冯诺依曼体系结构、计算机编码、定点数的表示、原码和补码的乘除法

这篇文章,主要介绍计算机组成原理之冯诺依曼体系结构、计算机编码、定点数的表示、原码和补码的乘除法。 目录 一、计算机组成 1.1、计算机发展历史 1.2、计算机硬件组成