SPFA
在稀疏图上运行效率较高,为 O(km) 级别,其中k是一个较小的常数。但在稠密图或特殊构造的网格图上,该算法仍可能退化为O(nm)
#include<iostream>
#include<queue>
#include<cstdio>
#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<int> 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<iostream>
#include<queue>
#include<cstdio>
#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 <int,int> > 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;
}
博客介绍了POJ 2387中涉及的SPFA和Dijkstra(堆优化)算法。SPFA在稀疏图上运行效率高,为O(km)级别,但在稠密图或特殊构造的网格图上可能退化为O(nm);Dijkstra(堆优化)时间复杂度为O(m log n)。
2418

被折叠的 条评论
为什么被折叠?



