zoukankan      html  css  js  c++  java
  • 图论算法伪代码(自己复习用)

    1.朴素版的dijkstra()算法(适用于稠密图)O(n^2):

    首先把dist都初始化为0x3f3f3f3f,然后1号点dist置0,然后进行n - 1次循环更新剩余的n - 1个点到1号点距离。

    循环内容:首先循环找到目前为止dist最小的而且不在集合当中的一个点t,然后用该点更新所有它可以到达的点。最后将点t加入集合。

    最后如果n号点的dist距离仍为inf,则到达不了,否则输出dist[n]。邻接矩阵存放图

    2.堆优化版的dijkstra()算法(适用于稀疏图)O(mlogn):

    我们可以把距离与对应点的信息放到小根堆里面,优化朴素版本寻找min dist的步骤,然后借助队列更新dist数组。邻接表存放图

    定义小根堆: priority<PII,vector,greater> heap;

    3.bellman_ford()算法(求限制步数的最短路问题) O(nm):

    如果步数限制为k,那么就循环k次,然后循环所有边,更新dist数组:dist[b] = min(dist[b], backup[a] + w);记得要用备份数组backup储存上一步的dist,以免发生串联

    4.SPFA算法 一般O(m), 最坏O(nm):

    对bellman_ford算法做出的优化算法,用队列存放dist更新了的点,宽搜优化。用st数组存放点是否在队列中的状态,当dist更新的话,如果!st[i],则更新st[i] = true;

    SPFA求负环:我们把所有点加入队列,然后通过队列维护cnt数组,如果cnt[i] >= n说明存在负环。

    5.floyd()算法 (多源汇最短路算法)O(n^3):

    首先初始化d[] [],然后三重循环k,i,j,d[i] [j] = min(d[i] [j], d[i] [k] + d[k] [j]);

    6.prim()算法 O(n^2):

    初始化dist数组为0x3f3f3f3f,然后迭代n次,每次找出不在集合中而且距离集合最短的点,将他加入集合,并用它更新其他点的距离dist。

    //模板
    int prim()
    {
        memset(dist, 0x3f, sizeof dist);
        
        int res = 0;
        
        for (int i = 0; i < n; i ++ )
        {
            int t = -1;
            for (int j = 1; j <= n; j ++ )
                if (!st[j] && (t == -1 || dist[t] > dist[j]))
                    t = j;
            
            if (i && dist[t] == INF) return INF;
            if (i) res += dist[t];
            
            for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], g[t][j]);
            
            st[t] = true;
        }
        
        return res;
    }
    
    7.kruskal()算法 O(mlogm):

    按边权重从小到大排序每条边(结构体存储,重载一个小于号),然后从小到大枚举,如果a,b不连通,那么就将他们连起来(并查集)。

    //存放边的结构体
    struct node
    {
        int a, b, w;
        
        bool operator< (const node & W)const
        {
            return w < W.w;
        }
    }edges[M];
    //并查集模板(加路径压缩)
    int find(int x)
    {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    //首先初始化并查集
    for (int i = 1; i <= n; i ++ ) p[i] = i;
    //cnt存放已加入的边的数量,ans为最小生成树权重之和
    int cnt = 0, ans = 0;
    for (int i = 0; i < m; i ++ )
    {
    	int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            
        a = find(a), b = find(b);
        if (a != b)
        {
            p[a] = b;
            cnt ++ ;
            ans += w;
         }
    }
    
    8.染色法判断二分图 O(n + m):

    首先for循环迭代每个点,如果这个点还没有染色,那么就将这个点染色,然后dfs它的所有临点,并且将没有染过色的临点染色成另外一种颜色,如果临点已经染过色了那么判断相邻两点颜色是否一致,一致的话返回false。

    //part
    bool flag = true;
        for (int i = 1; i <= n; i ++ )
        {
            if (!color[i])
            {
                if (!dfs(i, 1))
                {
                    flag = false;
                    break;    
                }
            }
        }
    
    //dfs
    bool dfs(int u, int c)
    {
        color[u] = c;
        
        for (int i = h[u]; ~i; i = ne[i])
        {
            int j = e[i];
            if (!color[j])
            {
                if (!dfs(j, 3 - c)) return false;
            }
            if (color[j] == c) return false;
        }
        return true;
    }
    
    9.匈牙利算法 O(mn)实际运行效果很好:

    首先邻接表存左边到右边的一条边,因为不需要反向访问,所以不用存右边到左边的边。然后st数组存放每个右边的点在本次是否被访问过(如果没有st数组,假如碰到环了会死循环),match数组存放和右边匹配的左边的点。接着循环左边所有点,如果find(i)可以匹配到,那么答案++。find函数:访问x的所有临边j,如果st[j] == 0即未被访问,那么就访问它,然后看j是否有match,如果有的话看一下是否可以把j的match换一个匹配即find(match[j]),如果可以就换,然后把x与j匹配起来。

    匈牙利算法部分重要代码:
    bool find(int x)
    {
        for (int i = h[x]; ~i; i = ne[i])
        {
            int j = e[i];
            if (!st[j])
            {
                st[j] = true;
                if (!match[j] || find(match[j]))
                {
                    match[j] = x;
                    return true;
                }
            }
        }
        
        return false;
    }
    
  • 相关阅读:
    大数据学习笔记之一:大数据初识
    从漏洞中总结编程规范(转发)+自我补充
    软件性能测试的基本概念和计算公式(转发)
    系统吞吐量、TPS(QPS)、用户并发量、性能测试概念和公式(转发)
    Linux学习记录(三):time 相关
    Linux报错第一弹: /bin/sh^M: bad interpreter: No such file or directory
    Linux学习记录(二)----if
    SVN 提交出错1
    java.lang.NoClassDefFoundError
    git 将文件取消版本控制
  • 原文地址:https://www.cnblogs.com/scl0725/p/14003479.html
Copyright © 2011-2022 走看看