核心思路
记录能从起点走到的点的最小边权和,然后不断更新直到所有节点遍历完或者不能在遍历新的节点
Single Source Shortest Path I
https://cn.vjudge.net/problem/Aizu-ALDS1_12_B
Single Source Shortest Path
For a given weighted graph G = ( V , E ) G = (V, E) G=(V,E), find the shortest path from a source to each vertex. For each vertex u u u, print the total weight of edges on the shortest path from vertex 0 0 0 to u u u.
Input
In the first line, an integer n n n denoting the number of vertices in G G G is given. In the following n n n lines, adjacency lists for each vertex u u u are respectively given in the following format:
u u u k k k v 1 v_1 v1 c 1 c_1 c1 v 2 v_2 v2 c 2 c_2 c2 … v k v_k vk c k c_k ck
Vertices in G G G are named with IDs 0 , 1 , . . . , n − 1 0, 1, ..., n-1 0,1,...,n−1. u u u is ID of the target vertex and k k k denotes its degree. v i ( i = 1 , 2 , . . . k ) v_i (i = 1, 2, ... k) vi(i=1,2,...k) denote IDs of vertices adjacent to u u u and c i c_i ci denotes the weight of a directed edge connecting u u u and v i v_i vi (from u u u to v i v_i vi).
Output
For each vertex, print its ID and the distance separated by a space character in a line respectively. Print in order of vertex IDs.
Constraints
1 ≤ n ≤ 100 1 \leq n \leq 100 1≤n≤100
0 ≤ c i ≤ 100 , 000 0 \leq c_i \leq 100,000 0≤ci≤100,000
∣ E ∣ ≤ 10 , 000 |E| \leq 10,000 ∣E∣≤10,000
All vertices are reachable from vertex 0 0 0
Sample Input 1
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3
Sample Output 1
0 0
1 2
2 2
3 1
4 3
Reference
Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.
#include
using namespace std;
const int MAX=100;
const int INFTY=(1<<21);
const int WHITE=0;
const int GRAY=1;
const int BLACK=2;
int n,m[MAX][MAX];//邻接矩阵 记录从u->v的边权
void dijkstra(){
int minv;
int d[MAX];//用于记录起点s到v的最短路
int color[MAX];//用来记录访问状态 WHITE GRAY BLACK
for(int i=0;i<n;i++){
d[i]=INFTY;
color[i]=WHITE;
}
d[0]=0;
color[0]=GRAY;
while(1){
minv=INFTY;
int u=-1;
for(int i=0;i<n;i++){//在当前节点下寻找边权最小的子节点
if(minv > d[i]&&color[i]!=BLACK){
u=i;
minv=d[i];
}
}
if(u==-1) break;//遍历完整棵树
color[u]=BLACK;//表明u进入目前所生成的最短路,不可修改
for(int v=0;v<n;v++){//存u的最短路
if(color[v]!=BLACK&&m[u][v]!=INFTY)
if(d[v]>d[u]+m[u][v]){
d[v]=d[u]+m[u][v];
color[v]=GRAY;
}
}
}
for(int i=0;i<n;i++){
cout<<i<<" "<<(d[i]==INFTY ? -1 : d[i])<<endl;
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
m[i][j]=INFTY;
}
}
int k,c,u,v;
for(int i=0;i<n;i++){
cin>>u>>k;
for(int j=0;j<k;j++){
cin>>v>>c;
m[u][v]=c;
}
}
dijkstra();
}
Single Source Shortest Path II
https://cn.vjudge.net/problem/Aizu-ALDS1_12_C
For a given weighted graph G=(V,E), find the shortest path from a source to each vertex. For each vertex u, print the total weight of edges on the shortest path from vertex 0 to u.
Input
In the first line, an integer n denoting the number of vertices in G is given. In the following n lines, adjacency lists for each vertex u are respectively given in the following format:
u k v1 c1 v2 c2 … vk ck
Vertices in G are named with IDs 0,1,…,n−1. u is ID of the target vertex and k denotes its degree. vi(i=1,2,…k) denote IDs of vertices adjacent to u and ci denotes the weight of a directed edge connecting u and vi (from u to vi).
Output
For each vertex, print its ID and the distance separated by a space character in a line respectively. Print in order of vertex IDs.
Constraints
1≤n≤10,000
0≤ci≤100,000
|E|<500,000
All vertices are reachable from vertex 0
Sample Input 1
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3
Sample Output 1
0 0
1 2
2 2
3 1
4 3
Reference
Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.
#include
#include
#include
using namespace std;
const int MAX=10000;
const int INFTY=(1<<21);
const int WHITE=0;
const int GRAY=1;
const int BLACK=2;
int n;
vector< pair<int,int> >adj[MAX];//加权有向图的邻接表表法
void dijkstra(){
priority_queue< pair<int,int> > PQ;//有限队列存存最小节点(默认优先级较大)
int color[MAX],d[MAX];
for(int i=0;i<n;i++){//初始化
d[i]=INFTY;
color[i]=WHITE;
}
d[0]=0;
PQ.push(make_pair(0,0));//起点
color[0]=GRAY;
while(!PQ.empty()){
pair<int,int> f = PQ.top();
PQ.pop();
int u=f.second;
color[u]=BLACK;
//取出最小值,若不是最短路则忽略
if(d[u] < f.first*(-1)) continue;
for(int j=0; j<adj[u].size(); j++){
int v=adj[u][j].first;
if(color[v]==BLACK) continue;
if(d[v]>d[u]+adj[u][j].second){
d[v]=d[u]+adj[u][j].second;
PQ.push(make_pair(d[v]*(-1),v));// priority_queue(默认优先级较大)所以要*-1;
color[v]=GRAY;
}
}
}
for(int i=0;i<n;i++){
cout<<i<<" "<<(d[i]==INFTY ? -1 : d[i])<<endl;
}
}
int main(){
cin>>n;
int k,c,u,v;
for(int i=0;i<n;i++){
cin>>u>>k;
for(int j=0;j<k;j++){
cin>>v>>c;
adj[u].push_back(make_pair(v,c));
}
}
dijkstra();
return 0;
}