有关最短路相信大家都是知道的,即求一个图中单源单汇点最短路径,单源多汇点最短路径,任意两点间最短路径,判断负权回路等做法。
=_=
1.floyed
i->j
=>dis[i][j]
=>dis[i][j]
i->k,k->j
=>dis[i][k]+dis[k][j]
若经过中间点使距离变小,则更新。
代码如下:
void floyed()
{
for (int k=1;k<=n;k++;)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (dis[i][k]+dis[k][j]<dis[i][j])
dis[i][j]=dis[i][k]+dis[k][j];
}=_=2.dijkstra
其实是贪心,不能有负环,如果源点到某个点的距离是到其他点的距离的最小值,能么就更新。
代码如下:
void dijkstra(int st)
{
for (int i=1;i<=n;i++)
dis[i]=a[st][i];
memset(vis,0,sizeof(vis));
vis[st]=1;
dis[st]=0;
for (int i=1;i<n;i++)
{
int minn=99999999;
int k=0;
for (int j=1;j<=n;j++)
if (!vis[j]&&dis[j]<minn)
{
minn=dis[j];
k=j;
}
if (!k)
return ;
vis[k]=1;
for (int j=1;j<n;j++)
if (!vis[j]&&dis[k]+a[c][j]<dis[j])
dis[j]=dis[k]+a[k][i];
}
}=_=
3.bellman_ford
求单源点到其他点的最短距离,并判断是否有负环。
代码如下:
bool bellman_ford()
{
memset(dis,0,sizeof(dis));
dis[st]=0;
bool rel=0;
for (int i=1;i<=n;i++)
{
rel=0;
for (int j=1;j<=sumn;j++)
if (dis[a[j].x]+a[j].v<dis[aij].v)
{
dis[a[i].y]=a[j].v+dis[a[j].x];
rel=1;
}
if (!rel)
return 0;
}
return 1;
}=_=
4.SPFA(si pa fa 大法好)
使用邻接表,优化bellman_ford,节约时间和空间。
代码如下:
void SPFA()
{
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
vis[s]=1;
que[1]=s;
head=0;
tail=1;
while (head<tail)
{
int tn=q[++head];
vis[tn]=0;
int te=link[tn];
for (int i=te;i;i=e[i].next)
{
int tmp=e[i].y;
if (dis[tn]+e[i].v<dis[tmp])
{
dis[tmp]=dis[tn]+e[i].v;
if (!vis[tmp])
{
q[++tail]=tmp;
vis[tmp]=1;
}
}
}
}
return ;
}这四种方法都是求最短路的好方法,大家一起自己掌握。
(代码抄自教科书,但确实是自己好不容易打出来的)
本文介绍了最短路径问题,包括单源单汇点、单源多汇点和任意两点间最短路径的求解。讨论了Bellman-Ford算法、Floyd-Warshall算法、Dijkstra算法以及SPFA算法,并提供了相关代码实现。同时强调这些算法均不适用于存在负权回路的情况。
3640

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



