求最短路的四个模板

来源:互联网 发布:阿里云 1m带宽 编辑:程序博客网 时间:2024/06/05 01:08

那就是Floyd(5min),Dj(10min), Bellman(5min),Spfa(10min)
不多说都是模板,括号里是最好能在该时间内写完(然而除了Floyd和Spfa目前我都超时
题目就是n个点,m条路,无向图,带权值,问起点s到终点l的最短路

Floyd(最好写的算法)

#include<iostream>#include<algorithm>#include<cstring>using namespace std;int g[105][105],n,m;int main(){    int x,y,a,b,z;    scanf("%d%d",&n,&m);scanf("%d%d",&a,&b);    memset(g,0x3f,sizeof(g));    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&x,&y,&z);        g[x][y]=z;g[y][x]=z;    }    for(int i=1;i<=n;i++)     for(int j=1;j<=n;j++)      for(int k=1;k<=n;k++)       g[i][j]=min(g[i][j],g[i][k]+g[k][j]);    printf("%d",g[a][b]);    return 0;}

Dj(个人认为没什么实际用处的算法)

#include<cstdio>#include<cstring>using namespace std;int dis[105],g[105][105],n,m,s,l,v[105];void dj(){    for(int i=1;i<=n;i++)if(i!=s)dis[i]=0x3f3f3f3f;    for(int i=1;i<=n;i++)    {        int min1=0x3f3f3f3f,k=0;        for(int j=1;j<=n;j++)        {            if(v[j]==0&&dis[j]<min1)            {                min1=dis[j];                k=j;            }        }        if(!k) break;        v[k]=1;        for(int j=1;j<=n;j++)         if(dis[j]>dis[k]+g[k][j]&&v[j]==0)           {            dis[j]=dis[k]+g[k][j];           }    }    printf("%d",dis[l]);}int main(){    int x,y,z;    scanf("%d%d%d%d",&n,&m,&s,&l);    for(int i=1;i<=n;i++)     for(int j=1;j<=n;j++)      g[i][j]=0x3f3f3f3f;    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&x,&y,&z);        g[x][y]=z;g[y][x]=z;    }    dj();}

Bellman(也不是很有用的的算法)

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct node{    int u,v,w;}e[205];int n,m,t;int dis[105];void add(int u,int v,int w){    e[++t].v=v;    e[t].u=u;    e[t].w=w;}void bellman(int x,int y,int z){    printf("%d %d %d\n",dis[x],z,dis[y]);    if(dis[x]+z<dis[y])    dis[y]=dis[x]+z;}int main(){    int x,y,s,l,z;    scanf("%d%d%d%d",&n,&m,&s,&l);    for(int i=1;i<=n;i++)if(i!=s)dis[i]=0x3f3f3f3f;    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&x,&y,&z);        add(x,y,z);        add(y,x,z);    }    for(int i=1;i<=n-1;i++)     for(int j=1;j<=t;j++)      bellman(e[j].u,e[j].v,e[j].w);    printf("%d ",dis[l]);    return 0;}

Spfa(最常用最常见的算法)

#include<cstdio>#include<cstring>using namespace std;struct node{    int v,next,w;}e[205];int n,m,s,l,t;bool v[105];int q[1005],dis[105],h[105];void add(int u,int v,int w){    e[++t].v=v;    e[t].w=w;    e[t].next=h[u];    h[u]=t;}void spfa(int x){    int head=0,tail=1;    v[x]=1;    q[1]=x;    dis[x]=0;    while(head<tail)    {        int now=q[++head];v[now]=0;        for(int i=h[now];i;i=e[i].next)        {            int to=e[i].v;            if(dis[to]>dis[now]+e[i].w)            {                dis[to]=dis[now]+e[i].w;                if(!v[to])                {                    v[to]=1;                    q[++tail]=to;                }            }        }    }}int main(){    int x,y,z;    scanf("%d%d%d%d",&n,&m,&s,&l);    memset(dis,0x3f,sizeof(dis));    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&x,&y,&z);        add(x,y,z);        add(y,x,z);    }    spfa(s);    printf("%d",dis[l]);}

简单总结一下

Spfa是最常用的求最短路算法了,而Floyd因为是用邻接矩阵实际上并不常用,Dj的核心是用Prim求最小生成树,Bellman是可以用来求差分约束

原创粉丝点击