题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_12_B
以临界矩阵的形式给出一个有权图,要求出每个节点到顶点0的最短路径。使用dijkstra算法,思路如下:
dijkstra算法
初始化状态下将S置空。初始化s的d[s]=0,除s之外,所有属于V的顶点i的d[i]=∞
循环进行下述处理,直到S=V为止。从V-S中选出d[u]最小的顶点u,将u添加到S,同时将与u相邻且属于V-S的所有顶点v的值更新:
if(d[u] + w(u,v) < d[v])
d[v] = d[u] + w(u,v)
p[v] = u
d[v]中记录着从s出发,经由S内顶点抵达v的最短路径成本,即为V中的所有顶点d[v]都记录者s到v的最短路径成本。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxx=1010;
const int infinity=1<<30;
int A[maxx][maxx],d[maxx];
bool flag[maxx];
int n,a,b,c;
int main (){
cin>>n;
for(int i=0;i<n;i++){
flag[i]=false;
d[i]=infinity;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
A[i][j]=infinity;
}
}
for(int i=0;i<n;i++){
cin>>a>>b;
for(int j=0;j<b;j++){
cin>>c;
cin>>A[a][c];
}
}
d[0]=0;
while(1){
int minv=infinity,minj=-1;
for(int i=0;i<n;i++){
if(flag[i]==false && d[i]<minv){
minv=d[i];
minj=i;
}
}
if(minv==infinity) break;
flag[minj]=true;
for(int i =0;i<n;i++){
if(A[minj][i]!=infinity && flag[i]==false && d[i]>=d[minj]+A[minj][i]){
d[i]=d[minj]+A[minj][i];
}
}
}
for(int i=0;i<n;i++) cout<<i<<" "<<(d[i]==infinity ? -1 : d[i])<<endl;
return 0;
}
错点:
1.读入数据时,cin>>c;cin>>A[a][c];要分开写,如果写成cin>>c>>A[a][c];低版本的gcc读入会出现问题。
2.输出时d[i]==infinity ? -1 : d[i] 当无法到达时,输出-1
3.一个可能发生的问题,infinity最好不要设置太大(1<<30大概是1073741824,2倍就越界了,可以用1<<29),否则在算d[minj]+A[minj][i]的时候会出现2倍的infinity,可能会出错,这次没遇到