dijkstra算法是将所有的结点分为已定到初始点最短距离的一组和未定到初始点最短距离的一组。我们只要不断将未定的一组中的元素放入已定的一组就好了。
每次都保证进入已定组的结点为未定组到起点最短距离的最小值,因为只有这样我们才没办法通过未定组中的点到达该点(如果这样的话显然不是最短距离)
#define INF 0x3f3f3f3f
#define maxm 2005
int mapp[maxm][maxm];//邻接矩阵
int vis[maxm];//记录访问情况
int dis[maxm];//记录到初始点的最短距离
首先定义好我们需要的东西。
void initmymapp()
{
memset(mapp,INF,sizeof(mapp));//初始化到各边的距离
for(int i=1; i<maxm; i++)
{
mapp[i][i]=0;
}//到自身的距离设为0
}
接着初始化。
void getmymapp(int s,int t,int d)
{
int u,v,w;
while(s--)
{
scanf("%d%d%d",&u,&v,&w);//输入边
m=getmax(m,getmax(u,v));//得到结点数
if(mapp[u][v]>w)
{
mapp[u][v]=w;
mapp[v][u]=w;
}//给边赋值
}
for(int i=0; i<t; i++)
{
int x;
scanf("%d",&x);
mapp[0][x]=0;
mapp[x][0]=0;
}//由于有多个起点,我们虚构一个起点,用于连接这些起点,并将其权值赋值为0
m++;//当然结点数就要加1了
for(int i=0; i<d; i++)
{
int y;
scanf("%d",&y);
mapp[y][m+1]=0;
mapp[m+1][y]=0;
}//同理,由于有多个终点,我们虚构一个终点,用于连接这些终点,并将权值赋值为0
m++;//同理结点数加1
}
这样我们的绘图工作就完成了
接下来就是重点算法了
void dijkstra(int s)
{
memset(vis,0,sizeof(vis));//初始化所有结点为未定的状态
for(int t=1; t<=m; t++)
{
dis[t]=mapp[s][t];
}//初始化起点到各点的最短距离
vis[s]=1;//起点已定
for(int t=1; t<m; t++)//除结点外,我们还要处理m-1个结点
{
int minn=INF;//保存最短距离
int temp;//保存最短距离对应的下标
for(int i=1; i<=m; i++)
{
if(vis[i]!=1&&minn>dis[i])//未定组且到起点最短放入已定组
{
minn=dis[i];
temp=i;
}
}
vis[temp]=1;
for(int i=1; i<=m; i++)
{
if(dis[i]>mapp[temp][i]+dis[temp])
dis[i]=mapp[temp][i]+dis[temp];
}//更新到各点的最短距离,
}
}
当我们刷新n次后,到各点的最短距离也就出来了。
整个算法分为找未定组入已定组,和刷新最短距离。