zoukankan      html  css  js  c++  java
  • 最短路模板(Floyd+bellman+spfa+Dijkstra)

    最短路问题

    1、单源最短路

    a、所有权边都是正数:

           Dijkstra算法 :朴素算法(O(mn))  堆优化(O(mlogn))

    b、有负数权变:

           Bellman算法 :  O(mn)

           Spfa算法:(一般情况O(m),最坏情况 O(mn))   (慎用)

    2、多源最短路  

           Floyd算法: O(n^3)

    Dijkstra

    #include<bits/stdc++.h>
    #define ll long long
    #define MOD 998244353 
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    const int NUM = 1005;
    struct edge{
    	int from,to,w;
    	edge(int a,int b,int c){from=a;to=b;w=c;}
    };
    vector<edge>e[NUM];
    struct s_node{
    	int id,n_dis;
    	s_node(int b,int c){id=b;n_dis=c;}
    	bool operator < (const s_node &a) const
    	{return n_dis>a.n_dis;}
    };
    int n,m;
    int pre[NUM];
    void print_path(int s,int t)
    {
    	if(s==t)printf("%d",s);
    	print_path(s,pre[t]);
    	printf("%d",t);
    }
    void Dijkstra(int s)  //s是起点
    {
        int dis[NUM];
        bool done[NUM];
        for(int i=1;i<=n;i++){dis[i]=INF;done[i]=false;}
        dis[s]=0;
        ;priority_queue<s_node>Q
        Q.push(s_node(s,dis[s]));
        while(!Q.empty())
        {
        	s_node u=Q.top();
            Q.pop();
            if(done[u.id])continue;
            done[u.id]=true;
            for(int i=0;i<e[u.id].size();i++){
            	edge y=e[u.id][i];
            	if(done[y.to])continue;
            	if(dis[y.to]>y.w+u.n_dis){
            		dis[y.to]=y.w+u.n_dis;
            		Q.push(s_node(y.to,dis[y.to]));
            		pre[y.to]=u.id;
            	}
            }
        }
        printf("%d
    ",dis[n]);
    }
    int main()
    {
        while(~scanf("%d %d",&n,&m)){
        	if(n==0&&m==0)break;
        	for(int i=1;i<=n;i++){
        		e[i].clear();
        	}
        	for(int i=1;i<=m;i++){
        		int a,b,c;
                scanf("%d %d %d",&a,&b,&c);
                e[a].push_back(edge(a,b,c));
                e[b].push_back(edge(b,a,c));
        	}
        	Dijkstra(1);
        }
    	return 0;
    }
    
    //朴素
    //-----------------------
    const int NUM = 1005;
    int mp[NUM][NUM];
    int dis[NUM];
    bool vis[NUM];
    int n,m;
    void Dijkstra()
    {
        int pos=1,minn;
        for(int i=1;i<=n;i++)vis[i]=false;
        dis[1]=0;
        vis[1]=1;
        for(int i=1;i<=n;i++){
            minn=INF;
            for(int j=1;j<=n;j++){
                if(vis[j]==0&&minn>dis[j]){
                    minn=dis[j];
                    pos=j;
                }
            }
            vis[pos]=1;
            for(int j=1;j<=n;j++){
                if(vis[j]==0&&dis[j]>dis[pos]+mp[pos][j]){
                    dis[j]=dis[pos]+mp[pos][j];
                }
            }
        }
        printf("%d
    ",dis[n]);
    }

    Bellman

    #include<bits/stdc++.h> 
    #define ll long long
    #define MOD 998244353 
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    const int NUM = 105;
    struct edge{int u,v,w;}e[10005];
    int n,m,cnt;
    int pre[NUM];
    void print_path(int s,int t)
    {
        if(s==t){printf("%d",s); return 0;}
        print_path(s,pre[t]);
        printf("%d",t);
    }
    void bellman(int s)
    {
        int d[NUM];
        for(int i=1;i<=n;i++)d[i]=INF;
        d[s]=0;
        for(int k=1;k<=n;k++){
            for(int i=0;i<cnt;i++){
                int x=e[i].u, y=e[i].v;
                if(d[x]>d[y]+e[i].w){
                    d[x]=d[y]+e[i].w;
                    pre[x]=y;
                }
            }
        }
        printf("%d
    ",d[n]);
    }
    
    //----------------------------
    void bellman(int s) //负圈
    {
       int d[NUM];
       for(int i=1;i<=n;i++)d[i]=INF;
       d[s]=0;
       int k=0;
       bool update=true;
       while(update){
         k++;
         if(k>n){printf("有负圈");}
         for(int i=0;i<cnt;i++){
           int x=e[i].u,y=e[i].v;
           if(d[x]>d[y]+e[i].w){
              update=true;
              d[x]=d[y]+e[i].w;
              //pre[x]=y;
           }
         }
       }
       printf("%d
    ",d[n]);
    }
    
    
    int main()
    {
        while(~scanf("%d %d",&n,&m)){
            if(n==0||m==0)break;
            cnt=0;
            for(int i=1;i<=m;i++){
                int a,b,c;
                scanf("%d %d %d",&a,&b,&c);
                e[cnt].u=a; e[cnt].v=b; e[cnt].w=c; cnt++;
                e[cnt].u=b; e[cnt].v=a; e[cnt].w=c; cnt++;
            }
            bellman(1);   //从1到n的最短路
        }
        return 0;
    }

    spfa

    #include<bits/stdc++.h>
    #define ll long long
    #define MOD 998244353 
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    const int NUM=105;
    struct edge{
    	int to,next,w;
    	edge(int a,int b,int c){to=a;next=b;w=c;}
    };
    vector<edge>e[NUM];
    int n,m;
    int pre[NUM];
    void print_path(int s,int t)
    {
       if(s==t)printf("%d",s);
       print_path(s,pre[t]);
       printf("%d",t);
    }
    void spfa(int s)
    {
        int dis[NUM];
        bool inq[NUM];
        int neg[NUM];
        for(int i=1;i<=n;i++){dis[i]=INF;inq[i]=false;neg[i]=0;}
        dis[s]=0;
    	neg[s]=1;
    	queue<int>Q;
    	Q.push(s);
    	inq[s]=true;
    	while(!Q.empty())
    	{
    		int u=Q.front();
    		Q.pop();
    		inq[u]=false;
    		for(int i=0;i<e[u].size();i++){
    			int v=e[u][i].next,w=e[u][i].w;
    			if(dis[v]>dis[u]+w){
    				dis[v]=dis[u]+w;
    				pre[v]=u;
    				if(!inq[v]){
                       Q.push(v);
                       inq[v]=true;
                       neg[v]++;
                       if(neg[v]>n){printf("有负圈
    ");return;}
    				}
    			}
    		}
    	}
    	printf("%d
    ",dis[n]);
    	return;
    }
    int main()
    {
    	while(~scanf("%d %d",&n,&m)){
    		if(n==0&&m==0)break;
    		for(int i=1;i<=n;i++){
    			e[i].clear();
    		}
    		for(int i=1;i<=m;i++){
    			int a,b,c;
    			scanf("%d %d %d",&a,&b,&c);
    			e[a].push_back(edge(a,b,c));
    			e[b].push_back(edge(b,a,c));
    		}
    		spfa(1);
    	}
    	return 0;
    }

    Floyd

    #include<bits/stdc++.h>
    #define ll long long
    #define MOD 998244353 
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    const int NUM = 105;
    int graph[NUM][NUM];
    int n,m;
    void Floyd(int s)
    {
    	for(int k=1;k<=n;k++){
    		for(int i=1;i<=n;i++){
    			if(graph[i][k]!=INF){
    				for(int j=1;j<=n;j++){
    					if(graph[i][k]+graph[k][j]<graph[i][j])graph[i][j]=graph[i][k]+graph[k][j];
    				}
    			}
    		}
    	}
    	printf("%d
    ",graph[s][n]);
    }
    int main()
    {
    	while(~scanf("%d %d",&n,&m)){
    		if(n==0&&m==0)break;
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=n;j++){
    				graph[i][j]=INF;
    			}
    		}
    		for(int i=1;i<=m;i++){
    			int a,b,c;
    			scanf("%d %d %d",&a,&b,&c);
    			graph[a][b]=c;
    			graph[b][a]=c;
    		}
    		Floyd(1);
    	}
    	return 0;
    }
    越自律,越自由
  • 相关阅读:
    JavaScript常用设计模式
    js 判断l对象类型
    JavaScript编程(终极篇)
    微信小程序开发-滑动操作
    解决Jquery向页面append新元素之后事件的绑定问题
    C# list与数组互相转换
    C# “贝格尔”编排法
    C#数字格式化
    SQL从一个表查询数据插入/更新到另一个表
    全局唯一标识符 (GUID)
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13435574.html
Copyright © 2011-2022 走看看