zoukankan      html  css  js  c++  java
  • spfa+向前星

    SPFA(Shortest Path Faster Algorithm)(队列优化)算法是求单源最短路径的一种算法,在Bellman-ford算法的基础上加上一个队列优化,

    减少了冗余的松弛操作,是一种高效的最短路算法.......听说他跟dijkstra+heap更配噢!

    至于向前星,就是储存边的一种方式,我自己也不熟,有时候用向前星储存边会比邻接表更快,是因为边太多吗?我也不知道,但是下面这个坑爹题

    好像似乎就是这样的->_->

    poj 3159.Candies

    听说是什么差分约束系统,小朋友分糖,某个小朋友说自己不能比谁谁谁少多少颗糖,最后问第一个和最后那个最大相差多少颗糖(好像是这样的)

    转换为最短路,然后套用spfa算法,这里不用队列优化,用的是栈,其实就是改个名不用纠结...看代码:

    // poj 3159. Candies
    // 向前星+spfa+stack
    // spfa+栈实现其实就是dfs,还加上了负环的判断 
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    int n;
    const int N=300005;    //储存边的数量,因为向前星是储存边的 
    const int INF=0x3f3f3f3f;
    
    struct node {
        int v;
        int w;
        int next;
    };
    
    node edge[N];
    int adj[N];
    int dis[N];
    bool vis[N];
    int sta[N];
    int size;
    int in[N];
    
    void add_edge(int u, int v, int w)  
    {  
        edge[size].v = v;  
        edge[size].w = w;  
        edge[size].next = adj[u];  //边的next指向下一条边 
        adj[u] = size++;     //储存是第几条边 
    }
    
    int spfa(int s)
    {
        int top=0;
        int u, w, v;
        for(int i=1; i<=n; i++)
        {
            dis[i]=INF;
            vis[i]=0;
        }
        dis[s]=0;
        vis[s]=1;
        sta[top++]=s;    //模拟栈 
        while(top)
        {
            u = sta[--top];
            vis[u]=0;
            //int len=graph[u].size();
            //for(int i=0; i<len; i++)
            for(int i=adj[u]; i!=-1; i=edge[i].next)    //找相同起点的边 
            {
                //w = graph[u][i].w;
                //v = graph[u][i].v;
                v = edge[i].v;  
                w = edge[i].w; 
                if(dis[u] + w < dis[v])
                {
                    dis[v] = dis[u] + w;
                    if(!vis[v])
                    {
                        in[v]++;
                        if(in[v] > n)    //存在一点入队次数大于总顶点数,有负环 
                            return -1;
                        vis[v]=1;
                        sta[top++]=v;
                    }
                }
            }
        }
        return dis[n];
    }
    
    int main()
    {
        int m, u, v, w;
        while(scanf("%d%d", &n, &m) != EOF)
        {
            for (int i=0; i<=n; i++) 
                adj[i] = -1;  
            //memset(graph, 0, sizeof(graph));
            memset(vis, 0, sizeof(vis));
            size = 0;
            for(int i=0; i<m; i++)
            {
                scanf("%d%d%d", &u, &v, &w);
                add_edge(u, v, w);
                //graph[u].push_back(node(v, w));
            }
            spfa(1);
            printf("%d
    ", dis[n]);
        }
        return 0;
    }
    references:
      http://blog.sina.com.cn/s/blog_64018c250100ugck.html
      http://www.cnblogs.com/kuangbin/archive/2012/08/17/2644685.html 

  • 相关阅读:
    设计模式-简单工厂模式、工厂模式、抽象工厂模式-(创建型模式)
    设计模式-类间关系
    设计模式-六大基本原则
    设计模式-总起
    [转载]常见的移动端H5页面开发遇到的坑和解决办法
    [转载]Angular4 组件通讯方法大全
    【angular5项目积累总结】文件下载
    【转载】Vue 2.x 实战之后台管理系统开发(二)
    [转载]Vue 2.x 实战之后台管理系统开发(一)
    WordPress翻译中 __()、_e()、_x、_ex 和 _n 的用法及区别
  • 原文地址:https://www.cnblogs.com/dominjune/p/4713504.html
Copyright © 2011-2022 走看看