最短路大全

前言

最短路是算法中比较常用的,它的思想也贯穿着整个竞赛的。
这里蒟蒻我就总结一下。

Floyd

Code:

    struct Floyd{//O(n^3)
        int dis[N][N];
        void solve(){
            //这里dis在读入前初始为INF,一边读一边存边 
            for(int k=1;k<=n;++k)
                for(int i=1;i<=n;++i)
                    for(int j=1;j<=n;++j)
                        dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);   
        }
    }Floyd;

Bellman

Code:

    struct Bellman{//O(n*m) 
        struct edge{
            int from,to,cost;
        }es[M<<1];
        int dis[N];
        void solve(int s){
            memset(dis,0x3f3f3f3f,sizeof(dis));
            dis[s]=0;
            while(1){
                bool f=1;
                for(int i=1;i<=m;++i){//存边 
                    if(dis[es[i].from]!=INF && dis[es[i].to]>dis[es[i].from]+es[i].cost){
                        dis[es[i].to]=dis[es[i].from]+es[i].cost;
                        f=0;
                    }   
                }
                if(f)break;
            }
        }
    }Bellman;

Dijkstra

Code:

    struct Dijkstra{//O(n log m) 单点 
        bool vis[N]; 
        int dis[N];
        struct node{
            int to,d;
            bool operator<(const node &_)const{
                return d>_.d;
            }
        };
        vectorE[N];
        priority_queueQ;
        void solve(int s){
            memset(dis,0x3f3f3f3f,sizeof(dis));
            dis[s]=0;
            Q.push((node){s,0});
            while(!Q.empty()){
                node now=Q.top();Q.pop();
                int x=now.to;
                if(dis[x]continue;
                for(int i=0;i<(int)E[x].size();++i){
                    int y=E[x][i].to;
                    if(dis[y]>dis[x]+E[x][i].cost){
                        dis[y]=dis[x]+E[x][i].cost;
                        Q.push((node){y,dis[y]});
                    }
                }
            }
        }
    }Dijkstra;

SPFA

Code:

    struct SPFA{//O(nlogn)
        struct node{
            int to,cost;
        };
        vectorE[N];
        queue<int>Q;
        int dis[N];
        bool vis[N];
        void solve(int s){
            memset(dis,0x3f3f3f3f,sizeof(dis));
            memset(vis,0,sizeof(vis));
            Q.push(s);
            dis[s]=0;
            vis[s]=1;
            while(!Q.empty()){
                int x=Q.front();Q.pop();
                vis[x]=0;
                for(int i=0;i<(int)E[x].size();++i){
                    int y=E[x][i].to;
                    if(dis[y]>dis[x]+E[x][i].cost){
                        dis[y]=dis[x]+E[x][i].cost;
                        if(!vis[y]){
                            vis[y]=1;
                            Q.push(y); 
                        }
                    }
                } 
            }
        }
    }SPFA;

Summary:

  • 最短路在树上的题目是可以做为暴力分的,而且还是比较从简的。

你可能感兴趣的:(算法,图论,模板)