1.构成:前驱数组first【】,标记数组book【】,距离数组dis【】
前驱数组 first【】:用于存储起点x到最后第cnt条边,first【x】=cnt
eg:第一条边:1->2;第二条边:1->3;
存储为first【1】=2;
标记数组book【】:标记是否该点已被使用
结构体edge【++cnt】:第 cnt 条边,存储有关边的信息
edge【cnt】.to:第 cnt 条边的终点,指向下一个点 v(u->v)
edge【cnt】.w:第 cnt 条边的距离
edge【cnt】.next:以u为起点上一条边的编号(第cnt条边),
切记:edge【】数组对象针对“边”,故edge【】.next也存的边的信息。 edge[cnt].next=first[u];
2.利用方式:
for( i = first[ t ] ; i ! =0 ; i = edge[ i ].next )
if(!book[edge[i].to]&&dis[edge[i].to]>dis[t]+edge[i].w)
{ dis[edge[i].to]=dis[t]+edge[i].w; }① i 为边,以第 t 点为起点到达的最后一条边 i ;(t->v)
②当 i ! =0,则说明存在边时,进入for 循环;
③最后 i 为下一个点的最后一条边的编号,first【v】即为edge[ i ].next (t->v)
int cnt=1;
void add(int x,int y,int w)
{
edge[cnt].to=y; //指向终点 u->v
edge[cnt].next=first[x];//以u为起点上一条边的编号,也就是与这个边起点相同的上一条边的编号
edge[cnt].w=w; //权值(距离)
first[x]= cnt++; //更新以u为起点上一条边的编号
}
for(int i=first[t];i!=0;i=edge[i].next) //列举所有t连通的点
{
if(!book[edge[i].to]&&dis[edge[i].to]>dis[t]+edge[i].w)
{
dis[edge[i].to]=dis[t]+edge[i].w; //更新最短路径
}
}