最短路径问题:
在网络中,求两个不同顶点之间的所有路径中,边的权值之和最小的那一条路径
第一个顶点:源点
最后一个顶点:终点
单源最短路径问题:(无权、有权)
从某固定源点出发,求其到所有其他顶点的最短路径
多源最短路径问题:
求任意两顶点间的最短路径
无权图的单源最短路
只需要记录每个顶点最短路径上的前一个顶点;
就可以递归打出每个顶点到源点的最短路径。
dist[s]需要一开始被初始化为0,其他顶点的dist则应是明显无效值
1.有没有访问过可以用dist[w]有没有被初始化同时表示;
2.无权图的收录一开始就是有确定顺序的(BFS的队列),
即使有多个上层邻接点,因为第一个被收录的上层邻接点dist最小,因此第一次更新的(dist+1)也是最小的
具有相同上层邻接点v的结点dist相同(=dist[v]+1),(如果v比其他上层邻接点先收录);
3.有权图因为受其多个上层邻接点影响,未收录前,dist确定后仍有机会改变,第一个被收录的上层邻接点dist是其所有上层邻接点中最小的,但是E<v,w>则不一定;
无权图:dist[w]=dist[v]+1;
有权图:dist[w]=min{ dist[v]+E<v,w> , dist[w] }
#include <iostream>
#include <queue>
#define MAXN 1010
using namespace std;
int Nv,Ne;
struct LNode
{
int data;
LNode* next;
};
LNode* G[MAXN];
void CreateL(){
cin>>Nv>>Ne;
for(int i=0;i<Nv;i++){
G[i]=new LNode;
G[i]->data=i;
G[i]->next=NULL;
}
int v1,v2;
for(int i=0;i<Ne;i++){
cin>>v1>>v2;
LNode* tmp=new LNode;
tmp->data=v2;
tmp->next=G[v1]->next;
G[v1]->next=tmp;
/*LNode* tmp1=new LNode;
tmp1->data=v1;
tmp1->next=G[v2]->next;
G[v2]->next=tmp1;*/
}
}
void Unweighted(int S,int* dist,int* path){
queue<int> q;
q.push(S);
dist[S]=0;
int tmp;
while(!q.empty()){
tmp=q.front();
q.pop();
LNode* w=G[tmp]->next;
while(w){
if(dist[w->data]==-1){
dist[w->data]=dist[tmp]+1;
path[w->data]=tmp;
q.push(w->data);
}
w=w->next;
}
}
}
void PrintL(int start,int* path){
cout<<start;
int tmp=path[start];
while(tmp!=-1){
cout<<" "<<tmp;
tmp=path[tmp];
}
}
int main(){
CreateL();
int dist[MAXN],path[MAXN];
fill(dist,dist+Nv,-1);
fill(path,path+Nv,-1);
//从2出发到所有顶点的最短路径dist
Unweighted(2,dist,path);
//2到5的最短路径
PrintL(5,path);
return 0;
}
测试数据:
8 8
0 1
1 2
2 6
3 6
4 7
5 1
6 7
7 5