设为首页 加入收藏

TOP

【模板】最短路(一)
2018-10-22 00:10:03 】 浏览:56
Tags:模板 短路

①多源最短路

弗洛伊德算法(Floyd)

弗洛伊德算法基本思想就是:

(1) 最开始只允许经过1号顶点进行中转;

(2) 接下来只允许经过1和2号顶点进行中转,以此类推;

(3) 直到最后允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。

算法基本思路:在只经过前k号点的前提下,更新从i号顶点到j号顶点的最短路程

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int M=1e3+5;
int n,m,e[M][M];
void init()
{
    for(int i=1;i<=n;i++)  
        for(int j=1;j<=n;j++)  
            if(i==j) 
                e[i][j]=0;    
            else 
                e[i][j]=INF;  
                
    int u,v,w;  
    for(int i=1;i<=m;i++)  
    {  
        scanf("%d%d%d",&u,&v,&w);  
        e[u][v]=w;  
    }
}
void floyd()
{
    init();
    for(int k=1;k<=n;k++)  
        for(int i=1;i<=n;i++)  
            for(int j=1;j<=n;j++)  
                if(e[i][j]>e[i][k]+e[k][j])   
                    e[i][j]=e[i][k]+e[k][j];
}
int main()
{  
    cin>>n>>m;
    floyd();
    return 0;  
} 
floyd算法模板

 


②单源最短路

迪杰斯特拉算法(Dijkstra)

(1) 最基础的版本,时间复杂度O(2n2)

dist数组:初始点到其余各个顶点的最短路径;

vis数组:下标和dist数组对应;

<1>若值为false,则该点为未确定点,dist数组里的对应值是未确定的;

<2>若值为true,则该点为已确定点,dis数组里的对应值是确定的;

算法基本思路:每次找到离源点(我们目前指定的初始点就是1号顶点)最近的一个顶点,然后以该顶点为中心进行扩展,

不断更新源点到其余所有点的最短路径。

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxSize=1e3+5;
int n,m,e[maxSize][maxSize],dist[maxSize];
void dijkstra(int x)
{
    int vis[maxSize],i,j,u,minn;
    for(i=1;i<=n;i++)
    {
        dist[i]=e[x][i];
        vis[i]=0;
    } 
    vis[x]=1;
    for(i=1;i<n;i++)
    {
        minn=INF; 
        for(j=1;j<=n;j++)
            if(!vis[j]&&dist[j]<minn)
            {
                u=j;
                minn=dist[j];
            }
        vis[u]=1;
        for(j=1;j<=n;j++)
            if(!vis[j]&&dist[j]>dist[u]+e[u][j])
                dist[j]=dist[u]+e[u][j];        
    }
}
int main()
{
    int i,j,u,v,w,x;
    while(cin>>n>>m)
    {
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                if(i==j)e[i][j]=0;  
                else e[i][j]=INF;
        for(i=1;i<=m;i++)
           {
            scanf("%d%d%d",&u,&v,&w);
            e[u][v]=w;
        }
        cin>>x;
        dijkstra(x);
        for(i=1;i<=n;i++)
            cout<<dist[i]<<" ";
    }
    return 0;
}
dijkstra基础算法

(2) 链式前向星版本,时间复杂度O(n2

dis数组:初始点s到其余各个顶点的最短路径;

算法基本思路:从初始点开始作为中介点u,不断加入以中介点u为起点的已存在边的终点v,如果dis[u]+这条边的权值w<dis[v],则更新dis[v]。

#include<bits/stdc++.h>
using namespace std;
#define MAX 105 
#define INF 0x3f3f3f3f
int head[MAX],dis[MAX],cn;
struct edge
{
    int w,to,next;
}e[MAX*MAX];
void add(int u,int v,int w)
{
    e[++cn].w=w;
    e[cn].next=head[u];
    e[cn].to=v;
    head[u]=cn; 
} 
void dij(int s)
{
    int he=0,ta=0,qu[MAX*MAX],i;
    qu[ta++]=s;
    dis[s]=0;
    while(he<ta)
    {
        int u=qu[he++];
        for(i=head[u];i!=-1;i=e[i].next)
        {
            edge x=e[i];
            if(dis[x.to]>dis[u]+x.w)
            {
                dis[x.to]=dis[u]+x.w;
                qu[ta++]=x.to;
            }
        }
    }
} 
int main()
{
    int n,m,i;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(dis,INF,sizeof(dis));
        memset(head,-1,sizeof(head));
        for(i=1;i<=m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        int s;
        cin>>s;
        dij(s);
        for(i=1;i<=n;i++)
        cout<<dis[i]<<" ";
    }
}
dijkstra链式前向星版本

(3) vector邻接表版本,时间复杂度O(n2)

算法基本思路:与链式前向星版本同理。

#include<bits/stdc++.h>
using namespace std;
#define MAX 10005
#define INF 0x3f3f3f3f
typedef pair<int,int> pii;
vecto
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇第13届广东工业大学ACM校赛L-用来.. 下一篇IPv4地址结构体sockaddr_in详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目