最短路模板(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\n",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\n",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\n",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\n",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("有负圈\n");return;}
				}
			}
		}
	}
	printf("%d\n",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\n",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;
}

 

posted @ 2020-07-13 19:49  hachuochuo  阅读(79)  评论(0编辑  收藏  举报