spfa dijkstra堆优化

POJ 2387

SPFA

在稀疏图上运行效率较高,为 O(km) 级别,其中k是一个较小的常数。但在稠密图或特殊构造的网格图上,该算法仍可能退化为O(nm)

#include
#include
#include
#define inf 1000000000
using namespace std;
typedef long long ll;
const int N=1010;
int n,m,tot;
int head[1010],ver[4010],edge[4010],Next[4010],d[1010],vis[1010];
void init()
{
    tot=0;
    for(int i=1;i<=n;i++)
        {d[i]=inf;head[i]=0;vis[i]=0;}
    for(int i=1;i<=m*2;i++)
        {ver[i]=0;edge[i]=0;Next[i]=0;}
}
void add(int x,int y,int z)
{
    ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
}
void spfa(int x)
{
    queue q;
    q.push(x);
    d[x]=0;
    vis[x]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for(int i=head[x];i;i=Next[i])
        {
            int y=ver[i],z=edge[i];
            if(d[y]>d[x]+z)
            {
                d[y]=d[x]+z;
                if(vis[y]==0)
                    {q.push(y);vis[y]=1;}
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        init();
        int x,y,z;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        spfa(1);
        printf("%d\n",d[n]);
    }
    return 0;
}

dijkstra (堆优化)

时间 O (m log n )

#include
#include
#include
#define inf 1000000000
using namespace std;
typedef long long ll;
const int N=1010;
int n,m,tot;
int head[1010],ver[4010],edge[4010],Next[4010],d[1010],vis[1010];
void init()
{
    tot=0;
    for(int i=1;i<=n;i++)
        {d[i]=inf;head[i]=0;vis[i]=0;}
    for(int i=1;i<=m*2;i++)
        {ver[i]=0;edge[i]=0;Next[i]=0;}
}
void add(int x,int y,int z)
{
    ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
}
void dijkstra(int x)
{
    priority_queue< pair  > q;
    d[x]=0;
    q.push(make_pair(-d[x],x));
    while(!q.empty())
    {
        int x=q.top().second;
        q.pop();
        if(vis[x]==1)
            continue;
        vis[x]=1;
        for(int i=head[x];i;i=Next[i])
        {
            int y=ver[i],z=edge[i];
            if(d[y]>d[x]+z)
                {d[y]=d[x]+z;q.push(make_pair(-d[y],y));}
        }
    }
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        init();
        int x,y,z;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        dijkstra(1);
        printf("%d\n",d[n]);
    }
    return 0;
}

 

你可能感兴趣的:(模板题)