先说迪杰斯特拉,先看题目吧。
这题就是迪杰斯特拉的路径记录算法题啊,还记录了最小路径个数。
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
int dis[550];
int num[550];
bool vis[550];
int ne[550];
int p[550];
int g[550][550];
int n,m,s,d;
int path[550];
void out(int b)//这里就是路径的输出简单的递归。
{
if(ne[b]==-1)
{
cout<<b<<' ';
return ;
}
out(ne[b]);
cout<<b<<' ';
}
void dij()
{
int tmp;
dis[s]=0;
num[s]=p[s];
ne[s]=-1;
int x;
path[s]=1;
for(int i=0;i<n;i++)
{
tmp=inf;
for(int j=0;j<n;j++)
{
if(!vis[j]&&tmp>dis[j])
{
x=j;
tmp=dis[j];
}
}
vis[x]=1;
for(int j=0;j<n;j++)
{
if(!vis[j]&&dis[x]+g[x][j]<dis[j])
{
path[j]=path[x];
dis[j]=dis[x]+g[x][j];
num[j]=num[x]+p[j];
ne[j]=x;//记录路径这里表示j在最短路的上一个节点是x,这样我们之前记录了x的前一个节点这样一步一步往前推就可以推到源点了。
}
else if(!vis[j]&&dis[j]==dis[x]+g[x][j])
{
path[j]+=path[x];
if(num[j]<num[x]+p[j])
{
num[j]=num[x]+p[j];
ne[j]=x;
}
}
}
}
cout<<path[d]<<' '<<num[d]<<endl;
out(ne[d]);
cout<<d<<endl;
}
int main()
{ int x,y,k;
cin>>n>>m>>s>>d;
memset(g,0x3f,sizeof(g));
memset(dis,0x3f,sizeof(dis));
for(int i=0;i<n;i++)
cin>>p[i];
for(int i=0;i<m;i++)
{
cin>>x>>y>>k;
g[x][y]=k;
g[y][x]=k;
}
dij();
}
下面是flyod记录路径了,应该是用了动态规划思想。
代码如下。
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
path[i][j]=k;//这就是记录路径的数组了。
}
}
输出路径的代码。
void out(int i,int j)
{
if(path[i][j]==0)
return ;
out(i,path[i][j]);
cout<<path[i][j];
out(path[i][j],j);
}
这里所用的思想就是path[i][j]表示从i 到 j 必须经过path[i][j];
然后i 到 path[i][j]的路径以及 path[i][j] 到 j 的路径。