【归纳】图论的各种基本算法的总结

图论的题也刷了不少了,但是近期才发现前面的一些dij什么的都忘记怎么写了,甚至分不清楚dij和spfa的区别了…所以想到这里做一些简单图论算法归纳。主要涉及的算法有:Floyd算法,dijkstra算法,spfa算法,prim算法和kruskal(其实这两个就是最小生成树算法),以及一维,二维的并查集算法(抱歉萌新最近也就学了这些算法大佬们见笑了QAQ)。


欧克!let’s begin !

首先,先说说几个算法中最简单的算法,floyd算法.

其实这个算法,就是依据动态规划原理,枚举出jk中间的一个点i以作为jk连接的桥梁,从而递推出任意两个点直接距离的最小值。有人问我i,j,k三个循环为什么不能调换位置,原因很简单,就是因为枚举ij之间的点k的时候只要用到前面的结论f(ji)和f(ik)的,所以ij必须是最快更新的一个,后面才能够用到。
虽然代码简单,但是时间复杂度o(n3),一不留神就超时了,注意数据。代码如下:

        for(int i=1;i<=n;i++)
        	for(int j=1;j<=n;j++)
        		for(int k=1;k<=n;k++)
			{
   
   
		                if(g[j][i]+g[i][k]<g[j][k])
	                        g[j][k]=g[j][i]+g[i][k];//先算出各个点之间的权值情况,前提是已经全部初始化gij=+∞,具体大小判断得依据题意
			}

dij算法.

原理:
1.先标记起点,然后从起点出发,得出到各个点的最小距离。
2.再每次找出离起点最近(并且之前还没有讨论过)的那个点,从这个点出发,将前面得到的起点到各个点的最短路径和以这个点为中介点,再到各个点的距离大小作比较,去最小值。时间复杂度o(n2)。
代码如下:


int i,j,t,flag[N],dis[N],g[N][N];
void dij()
{
   
   
    for(i=1;i<=t-1;i++)//起点不用讨论最后一个
    {
   
   
        int maxx=2e9,now=0;//最小值和当前最小值位置
        for(j=1;j<=t;j++)
        {
   
   
            if(!flag[j])//如果j未被讨论过
            {
   
   
                if(dis[j]<maxx)
                
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值