zoukankan      html  css  js  c++  java
  • 最短路径

    多源最短路径

    c.floyd

    /*
    多源最短路径
    floyd
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    #define MAXN 1010
    #define typec int
    #define INF 0x3f3f3f3f//防止后面溢出,这个不能太大
    int path[MAXN][MAXN];
    int cost[MAXN][MAXN],lowcost[MAXN][MAXN];
    
    void floyd(typec cost[][MAXN],typec lowcost[][MAXN],int n){
        int i,j,k;
        for(i=0;i<n;++i)
            for(j=0;j<n;++j){
                lowcost[i][j]=cost[i][j];
                if(i!=j&&cost[i][j]<INF)path[i][j]=i;
                else path[i][j]=-1;
            }
        for(k=0;k<n;++k)
            for(i=0;i<n;++i)
                for(j=0;j<n;++j)
                    if(lowcost[i][k]+lowcost[k][j]<lowcost[i][j]){
                        lowcost[i][j]=lowcost[i][k]+lowcost[k][j];
                        path[i][j]=path[k][j];
                    }
    }
    
    int main(){
        int n,m;//点数,边数
        int a,b,w,i,j;
        int s,t;//起点,终点
    
        while(~scanf("%d%d",&n,&m)){
            for(i=0;i<n;++i)
                for(j=0;j<n;++j)
                    cost[i][j]=INF;
            for(i=0;i<m;++i){
                scanf("%d%d%d",&a,&b,&w);
                if(w<cost[a][b])cost[a][b]=cost[b][a]=w;//
            }
            scanf("%d%d",&s,&t);
            floyd(cost,lowcost,n);
            if(s==t)printf("0
    ");
            else if(lowcost[s][t]!=INF)printf("%d
    ",lowcost[s][t]);
            else printf("-1
    ");
        }
        return 0;
    }
    View Code

    -----------------------

    c.Dijkstra单源最短路

    /*
    Dijkstra单源最短路
    权值必须是非负
    单源最短路径,Dijkstra算法,邻接矩阵形式,复杂度为O(n^2)
    求出源beg到所有点的最短路径,传入图的顶点数,和邻接矩阵cost[][]
    返回各点的最短路径lowcost[],路径pre[].pre[i]记录beg到i路径上的父结点,pre[beg]=-1
    可更改路径权类型,但是权值必须为非负
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    const int MAXN=1010;
    #define typec int
    const typec INF=0x3f3f3f3f;//防止后面溢出,这个不能太大
    bool vis[MAXN];
    int pre[MAXN];
    void Dijkstra(typec cost[][MAXN],typec lowcost[],int n,int beg){
        for(int i=0;i<n;i++){
            lowcost[i]=INF;vis[i]=false;pre[i]=-1;
        }
        lowcost[beg]=0;
        for(int j=0;j<n;j++){
            int k=-1;
            int Min=INF;
            for(int i=0;i<n;i++)
                if(!vis[i]&&lowcost[i]<Min){
                    Min=lowcost[i];
                    k=i;
                }
            if(k==-1)break;
            vis[k]=true;
            for(int i=0;i<n;i++)
                if(!vis[i]&&lowcost[k]+cost[k][i]<lowcost[i]){
                    lowcost[i]=lowcost[k]+cost[k][i];
                    pre[i]=k;
                }
        }
    }
    
    int main(){
        return 0;
    }
    View Code

    c2.Dijkstra算法+堆优化

    /*
    Dijkstra算法+堆优化
    使用优先队列优化,复杂度O(E log E)
    使用优先队列优化Dijkstra算法
    复杂度O(E log E)
    注意对vector<Edge>E[MAXN]进行初始化后加边
    */
    #include<iostream>
    #include<stdio.h>
    #include<vector>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int MAXN=1000010;
    struct qnode{
        int v;
        int c;
        qnode(int _v=0,int _c=0):v(_v),c(_c){}
        bool operator <(const qnode &r)const{
            return c>r.c;
        }
    };
    struct Edge{
        int v,cost;
        Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
    };
    vector<Edge>E[MAXN];
    bool vis[MAXN];
    int dist[MAXN];
    //点的编号从1开始
    void Dijkstra(int n,int start){
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=n;i++)dist[i]=INF;
        priority_queue<qnode>que;
        while(!que.empty())que.pop();
        dist[start]=0;
        que.push(qnode(start,0));
        qnode tmp;
        while(!que.empty()){
            tmp=que.top();
            que.pop();
            int u=tmp.v;
            if(vis[u])continue;
            vis[u]=true;
            for(int i=0;i<E[u].size();i++){
                int v=E[tmp.v][i].v;
                int cost=E[u][i].cost;
                if(!vis[v]&&dist[v]>dist[u]+cost){
                    dist[v]=dist[u]+cost;
                    que.push(qnode(v,dist[v]));
                }
            }
        }
    }
    void addedge(int u,int v,int w){
        E[u].push_back(Edge(v,w));
    }
    
    int main(){
    
        return 0;
    }
    View Code

    c3.单源最短路bellman_ford算法

    /*
    单源最短路bellman_ford算法
    单源最短khtkbellman_ford算法,复杂度O(VE)
    可以处理负边权图。
    可以判断是否存在负环回路。返回true,当且仅当图中不包含从源点可达的负权回路
    vector<Edge>E;先E.clear()初始化,然后加入所有边
    点的编号从1开始(从0开始简单修改就可以了)
    */
    #include<iostream>
    #include<stdio.h>
    #include<vector>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int MAXN=550;
    int dist[MAXN];
    struct Edge{
        int u,v;
        int cost;
        Edge(int _u=0,int _v=0,int _cost=0):u(_u),v(_v),cost(_cost){}
    };
    vector<Edge>E;
    //点的编号从1开始
    bool bellman_ford(int start,int n){
        for(int i=1;i<=n;i++)dist[i]=INF;
        dist[start]=0;
        //最多做n-1次
        for(int i=1;i<n;i++){
            bool flag=false;
            for(int j=0;j<E.size();j++){
                int u=E[j].u;
                int v=E[j].v;
                int cost=E[j].cost;
                if(dist[v]>dist[u]+cost){
                    dist[v]=dist[u]+cost;
                    flag=true;
                }
            }
            if(!flag)return true;//没有负环回路
        }
        for(int j=0;j<E.size();j++)
            if(dist[E[j].v]>dist[E[j].u]+E[j].cost)
                return false;//有负环回路
        return true;//没有负环回路
    }
    
    int main(){
    
        return 0;
    }
    View Code

    c4.单源最短路SPFA

    /*
    单源最短路SPFA
    时间复杂度O(kE)
    这个是队列实现,有时候改成栈实现会更加快,很容易修改
    这个复杂度是不定的
    */
    #include<iostream>
    #include<stdio.h>
    #include<vector>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int MAXN=1010;
    const int INF=0x3f3f3f3f;
    struct Edge{
        int v;
        int cost;
        Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
    };
    vector<Edge>E[MAXN];
    void addedge(int u,int v,int w){
        E[u].push_back(Edge(v,w));
    }
    bool vis[MAXN];//在队列标志
    int cnt[MAXN];//每个点的入队列次数
    int dist[MAXN];
    bool SPFA(int start,int n){
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=n;i++)dist[i]=INF;
        vis[start]=true;
        dist[start]=0;
        queue<int>que;
        while(!que.empty())que.pop();
        que.push(start);
        memset(cnt,0,sizeof(cnt));
        cnt[start]=1;
        while(!que.empty()){
            int u=que.front();
            que.pop();
            vis[u]=false;
            for(int i=0;i<E[u].size();i++){
                int v=E[u][i].v;
                if(dist[v]>dist[u]+E[u][i].cost){
                    dist[v]=dist[u]+E[u][i].cost;
                    if(!vis[v]){
                        vis[v]=true;
                        que.push(v);
                        if(++cnt[v]>n)return false;
                        //cnt[i] 为入队列次数,用来判定是否存在负环回路
                    }
                }
            }
        }
        return true;
    }
    
    int main(){
    
        return 0;
    }
    View Code
  • 相关阅读:
    常见问题汇总
    python的正则表达式
    Python 程序读取外部文件、网页的编码与JSON格式的转化
    第三方仓库PyPI
    文件名称一定不要设置为某些模块名称,会引起冲突!
    迟来的博客
    FENLIQI
    fenye
    Notif
    phpv6_css
  • 原文地址:https://www.cnblogs.com/gongpixin/p/5365200.html
Copyright © 2011-2022 走看看