思想:
(1)初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边<v,u>)或∞(若u不是v的出边邻接点)。
(2)从U中选取一个距离v最小的顶点k,把k加入S中(该选定的距离就是v到k的最短路径长度)。
(3)以k为新考虑的中间点,修改T中各顶点的距离:若从源点v到顶点u(u∈T)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边<k,u>上的权。
(4) 重复步骤(2)和(3)直到所有顶点都包含在S中。
矩阵
#include<cstdio>
#include<cstring>
using namespace std;
int i,j,k,n,m,x,y,h,minn,s;
int d[105][105],c[105];
bool f[105];
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(i=0;i<n;++i)
for(j=0;j<n;++j)
d[i][j]=2000000000;
memset(f,false,sizeof(f));
for(i=1;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&h);
d[x][y]=h;
}
f[s]=true;
for(j=0;j<n;++j) c[j]=d[s][j];
c[s]=0;
for(i=1;i<n;++i)
{
minn=2000000000;k=-1;
for(j=0;j<n;++j)
if((f[j]==false)&&(c[j]<minn))
{
minn=c[j];k=j;
}
if(k==-1) break;
f[k]=true;
for(j=0;j<n;++j)
if(c[j]>d[k][j]+c[k])
c[j]=d[k][j]+c[k];
}
for(j=0;j<n;++j)
printf("%d ",c[j]);
return 0;
}
邻接表
#include<cstdio>
#include<cstring>
using namespace std;
struct node{
int x,wi,next;
}a[210000];
int i,j,k,n,e,x1,y1,w1,qi;
int c[2005];
bool f[2005];
int main(){
scanf("%d%d%d",&n,&e,&qi);
for(i=0;i<n;++i){
a[i].x=i;a[i].next=0;
}
k=n;
for(i=1;i<=e;++i){
scanf("%d%d%d",&x1,&y1,&w1);
a[++k].next=a[x1].next;a[k].x=y1;a[k].wi=w1;a[x1].next=k;
}
for(i=0;i<n;++i) c[i]=2100000000;
memset(f,true,sizeof(f));
f[qi]=false;
c[qi]=0;
for(j=a[qi].next;j;j=a[j].next){
k=a[j].x;
c[k]=a[j].wi;
}
for(i=0;i<n;++i){
int minn=2100000000;
for(j=0;j<n;++j)
if(f[j]&&minn>c[j]){
minn=c[j];
k=j;
}
f[k]=false;
for(j=a[k].next;j;j=a[j].next){
int k1=a[j].x;
if(c[k1]>c[k]+a[j].wi)
c[k1]=c[k]+a[j].wi;
}
}
for(i=0;i<n;++i) printf("%d ",c[i]);
return 0;
}