欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

最短路

程序员文章站 2022-05-22 11:34:21
...

建图:邻接矩阵、链式前向星

(一)临接矩阵+dijikstra(O(n²))

int n,m,dis[1005],vis[1005],mapp[1005][1005];
void dijikstra(int s)
{
    for(int i=1;i<=n;i++) 
    {
        dis[i]=INF;
        vis[i]=0;
    }
    dis[s]=0;
    while(1)
    {
        int k=-1,len=INF;
        for(int i=1;i<=n;i++)  
            if(!vis[i]&&len>dis[i])
        {
            k=i;
            len=dis[i];
        }
        if(k==-1)break;
        vis[k]=1;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&dis[i]>dis[k]+mapp[k][i])
                dis[i]=dis[k]+mapp[k][i];
        }
    }
}
int main()
{
    int s,f;  //起点和终点
    while(~scanf("%d%d%d%d",&n,&m,&s,&f))  
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            mapp[i][j]=(i==j?0:INF);  //初始化,不能互通的距离为无穷
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            mapp[u][v]=mapp[v][u]=w;  //建图
        }
        dijikstra(s);
        printf("%d\n",dis[f]);
    }
    return 0;
}

(二)链式前向星+dijikstra(O(n²))

struct node
{
    int to,len;
    int next;
}mapp[1005];
int n,m,vis[1005],dis[1005],head[1005],cnt;
void addmap(int u,int v,int w)
{
    mapp[cnt].to=v;
    mapp[cnt].len=w;
    mapp[cnt].next=head[u];
    head[u]=cnt++;
}
void diji(int s)
{
    for(int i=1;i<=n;i++)
    {
        vis[i]=0;dis[i]=N;
    }
    dis[s]=0;
    while(1)
    {
        int k=-1,len=N;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&len>dis[i])
            {
                k=i;
                len=dis[i];
            }
        }
        if(k==-1) break;
        vis[k]=1;
        for(int i=head[k];i!=-1;i=mapp[i].next)
        {
            int t=mapp[i].to;
            if(!vis[t]&&dis[t]>dis[k]+mapp[i].len)
                dis[t]=dis[k]+mapp[i].len;
        }
    }
}
int main()
{
    int s,f;  //起点和终点
    while(~scanf("%d%d%d%d",&n,&m,&s,&f))
    {
        cnt=0;
        memset(head+1,-1,sizeof(head[0])*n);
        int u,v,w;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addmap(u,v,w);
            addmap(v,u,w);
        }
        diji(s);
        printf("%d\n",dis[f]);
    }
    return 0;
}

(三)邻接矩阵+floyd(O(n³))

int n,m,mapp[10005][10005];
int main()
{
    int s,f;  //起点和终点
    while(~scanf("%d%d%d%d",&n,&m,&s,&f))
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            mapp[i][j]=(i==j?0:INF);
        int u,v,w;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            mapp[u][v]=mapp[v][u]=w;
        }
        for(int k=1;k<=n;k++)  
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(mapp[i][j]>mapp[i][k]+mapp[k][j] )
                    mapp[i][j]=mapp[i][k]+mapp[k][j];
        printf("%d\n",mapp[s][f]);
    }
    return 0;
}

(四)邻接矩阵+spfa(O(nlogn~n²))

int n,m,mapp[1010][1010],vis[1010],dis[1010];
void spfa(int s)
{
    for(int i=1;i<=n;i++)
    {
        vis[i]=0;
        dis[i]=INF;
    }
    dis[s]=0;
    queue<int>q;
    q.push(s);  
    while(!q.empty())
    {
        int u=q.front();q.pop();
        vis[u]=0;
        for(int i=1;i<=n;i++)
        {
            if(dis[i]>dis[u]+mapp[u][i])
            {
                dis[i]=dis[u]+mapp[u][i];
                if(vis[i]==0)
              {
                  vis[i]=1;
                  q.push(i);
              }
            }
        }
    }
}
int main()
{
    int s,f;  //起点和终点
    while(~scanf("%d%d%d%d",&n,&m,&s,%f))
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                mapp[i][j]=(i==j?0:INF);
        int u,v,w;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            mapp[u][v]=w;
            mapp[v][u]=w;
        }
        spfa(s);
        printf("%d\n",dis[f]);
    }
    return 0;
}

(五)链式前向星+spfa(O(nlogn~n²))

struct node
{
    int to,len;
    int next;
}mapp[1005];
int n,m,vis[1005],dis[1005],head[M],cnt;
void addmap(int u,int v,int w)
{
    mapp[cnt].to=v;
    mapp[cnt].len=w;
    mapp[cnt].next=head[u];
    head[u]=cnt++;
}
void spfa(int s)
{
    for(int i=1;i<=n;i++)
    {
        vis[i]=0;dis[i]=N;
    }
    dis[s]=0;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        int k=q.front();q.pop();
        vis[k]=0;
        for(int i=head[k];i!=-1;i=mapp[i].next)
        {
            int t=mapp[i].to;
            if(dis[t]>dis[k]+mapp[i].len)
            {
                dis[t]=dis[k]+mapp[i].len;
                if(vis[t]==0)
                {
                    q.push(t);
                    vis[t]=1;
                }
            }
        }
    }
}
int main()
{
    int s,f;  //起点和终点
    while(~scanf("%d%d%d%d",&n,&m,&d,&f))
    {
        memset(head+1,-1,sizeof(head[0])*n);
                cnt=0;
        int u,v,w;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addmap(u,v,w);
            addmap(v,u,w);
        }
        spfa(s);
        printf("%d\n",dis[f]);
    }
    return 0;
}

 

相关标签: C/C++