zoukankan      html  css  js  c++  java
  • ACM模板——最短路

    #include <bits/stdc++.h>
    #define pb push_back
    #define _for(i,a,b) for(int i = (a);i < (b);i ++)
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    const int maxn = 50003;
    
    struct edge
    {
        int to;
        int cost;
    };
    vector<edge> G[maxn];
    //G[s].push_back(t);from s to t,directed
    
    int V,E;
    
    //from s to other V
    void shortest_path(int s)
    {
        
    }
    
    int main()
    {
        scanf("%d %d",&V,&E);
        _for(i,0,E)
        {
            int s,t,c;
            scanf("%d %d %d",&s,&t,&c);
            G[s].push_back(edge{t,c});
            G[t].push_back(edge{s,c});
        }
        shortest_path(0);
        cout << d[6] << endl;
    }
    
    /*
    10
    1 2
    2 5
    2 4
    3 6
    3 2
    4 10
    5 1
    5 3
    6 5
    6 9
    */
    main函数
    //from s to other V
    int d[maxn];
    void shortest_path(int s)
    {
        _for(i,0,V)
            d[i] = INF;
    
        d[s] = 0;
        while(1)
        {
            bool update = false;
            _for(i,0,V)
            {
                _for(j,0,G[i].size())
                {
                    edge e = G[i][j];
                    if(d[i] != INF && d[e.to] > d[i] + e.cost)
                    {
                        d[e.to] = d[i] + e.cost;
                        update = true;
                    }
                }
            }
            if(!update) break;
        }
    }
    Bellman-Ford
    //from s to other V
    bool used[maxn];
    int d[maxn];
    void shortest_path(int s)
    {
        _for(i,0,V)
        {
            d[i] = INF;
            used[i] = false;
        }
        d[s] = 0;
    
        while(1)
        {
            int v = -1;
            _for(i,0,V)
            if(!used[i] && (v==-1 || d[i] < d[v])) v = i;
    
            if(v==-1) break;
            used[v] = true;
    
            _for(i,0,G[v].size())
            d[G[v][i].to] = min(d[G[v][i].to],d[v]+G[v][i].cost);
        }
    }
    Dijkstra
    //from s to other V
    typedef pair<int,int> P;//first 是最短距离,second 是顶点编号 
    int d[maxn];
    void shortest_path(int s)
    {
        priority_queue<P,vector<P>,greater<P>> que;
        
        _for(i,0,V)
            d[i] = INF;
        d[s] = 0;
        que.push(P{0,s});
    
        while(!que.empty())
        {
            P p = que.top();que.pop();
            int v = p.second;
            if(d[v] < p.first) continue;
            _for(i,0,G[v].size())
            {
                edge e = G[v][i];
                if(d[e.to] > d[v] + e.cost)
                {
                    d[e.to] = d[v] + e.cost;
                    que.push(P{d[e.to],e.to});
                }
            }
        }
    }
    Dijkstra(priority_queue)
    //from s to other V
    typedef pair<int,int> P;//first 是最短距离,second 是顶点编号 
    int d[maxn];
    int pre[maxn];
    void shortest_path(int s)
    {
        priority_queue<P,vector<P>,greater<P>> que;
        
        _for(i,0,V)
            d[i] = INF;
        _for(i,0,V)
            pre[i] = -1;
        d[s] = 0;
        que.push(P{0,s});
    
        while(!que.empty())
        {
            P p = que.top();que.pop();
            int v = p.second;
            if(d[v] < p.first) continue;
            _for(i,0,G[v].size())
            {
                edge e = G[v][i];
                if(d[e.to] > d[v] + e.cost)
                {
                    d[e.to] = d[v] + e.cost;
                    que.push(P{d[e.to],e.to});
                    pre[e.to] = v;
                }
            }
        }
    }
    
    //到终点t 
    vector<int> get_path(int t)
    {
        vector<int> p;
        for(; t != -1;t = pre[t]) p.pb(t);
        reverse(p.begin(),p.end());
        return p;
    }
    Dijkstra(priority_queue)路径还原
    bool find_negative_loop()
    {
        memset(d,0,sizeof(d));
        _for(i,0,V)
            _for(j,0,V)
                _for(k,0,G[j].size())
                {
                    edge e = G[j][k];
                    if(d[e.to] > d[j] + e.cost)
                    {
                        d[e.to] = d[j] + e.cost;
                        if(i==V-1) return true;
                    }
                }
        return false;
    }
    判断负圈
    //from s to other V
    int d[maxn][maxn];
    void shortest_path()
    {
        memset(d,INF,sizeof(d));
        _for(i,0,V)
            _for(j,0,G[i].size())
            {
                edge e = G[i][j];
                d[i][e.to] = e.cost;
            }
        
        _for(k,0,V)
            _for(i,0,V)
                _for(j,0,V)
                    d[i][j] = min(d[i][j],d[i][k]+d[k][j]);
    }
    Floyd-Warshall
    //from s to other V
    //return false表示有负圈
    int d[maxn];// 距离数组 
    int vis[maxn];// 判断点是否在队列里 
    int pre[maxn];// 路径还原
    int cnt[maxn];// 进队列次数 
    bool shortest_path(int s)
    {
        memset(d,INF,sizeof(d));
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        memset(pre,-1,sizeof(pre));
        
        deque<int> q;
        d[s] = 0,cnt[s] = vis[s] = 1;
        q.push_back(s);
        while(!q.empty())
        {
            int now = q.front();q.pop_front();
            vis[now] = 0;
            _for(i,0,G[now].size())
            {
                if(d[G[now][i].to] > d[now] + G[now][i].cost)
                {
                    d[G[now][i].to] = d[now] + G[now][i].cost;
                    pre[G[now][i].to] = now;
                    if(!vis[G[now][i].to])
                    {
                        if(V == ++cnt[G[now][i].to]) return false;
                        if(!q.empty() && d[G[now][i].to] < d[q.front()])//队列非空且优于队首(SLF)
                            q.push_front(G[now][i].to);
                        else q.push_back(G[now][i].to);
                        vis[G[now][i].to] = 1;
                    }
                }
            }
        }
        return 0;
    }
    
    //到终点t 
    vector<int> get_path(int t)
    {
        vector<int> p;
        for(; t != -1;t = pre[t]) p.pb(t);
        reverse(p.begin(),p.end());
        return p;
    }
    SPFA(SLF优化,路径还原)

    Bellman O(|V|*|E|),可处理负边

    Dijkstra 优先队列实现 O(|E|*log|V|),不可处理负边

    Floyd O(|V^3|) d[i][i]为负数时可判定有负圈

    SPFA O(|V|*|E|),如果返回false则有负圈

  • 相关阅读:
    Python面向对象的魔术方法
    Python面向对象基础
    Python异常处理
    Python装饰器实现函数动态类型检查
    Python装饰器
    Python IO
    HTTP协议
    应用层常用协议
    读写分离
    MySQL优化三之MySQL配置
  • 原文地址:https://www.cnblogs.com/Asurudo/p/10566321.html
Copyright © 2011-2022 走看看