Dijkstra
/*
基本思想就是将所有结点分成两个集合,一个是st所在的集合,另一个是st不在的集合,每次从不包含st的集合中找出一个最优的结点加入到st所在的集合,并更新st到所有不在其所在集合中的点的距离。使用一个visit[]数组来标识结点在哪一个集合中。使用dist[]数组来记录st结点到其他结点的最短路径。
*/
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int const MAXN = 1000; const int INF = 1000000000; int g[MAXN][MAXN]; int dist[MAXN]; void Dijkstra(int st,int n) { bool visit[n]; memset(visit,false,sizeof(visit)); for(int i = 0; i < n; i++) { dist[i] = g[st][i]; } visit[st] = true; dist[st] = 0; for(int i = 0; i < n - 1 ; i++)//只需要n-1次,每次选出一个不再st结点集合中的结点并将 { //该结点放入到st结点所在的集合中 int u ; int temp = INF; for(int j = 0; j < n; j++)//选出一个不在st结点所在集合的最优结点 { if((!visit[j]) && (dist[j] < temp)) { u = j; temp = dist[j]; } } visit[u] = true; //cout<<"U "<<u<<endl; for(int k = 0; k < n; k++)//更新与初始结点之间的最短距离 { if((!visit[k]) && (dist[u] + g[u][k] < dist[k])) { dist[k] = dist[u] + g[u][k]; } } } } int main() { int n,st,ed; freopen("dijkstra.txt","r",stdin); while(cin >> n) { memset(g,0,sizeof(g)); memset(dist,0,sizeof(dist)); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { cin >> g[i][j]; if(g[i][j] == -1) g[i][j] = INF; } cin >> st >> ed; Dijkstra(st - 1,n);
cout<<"st = "<< st << " to ed = " << ed << " : \t"<< dist[ed - 1]<<endl; //for(int j = 0; j < n; j++) //cout<< dist[j] << " "; //cout<<endl; } return 0; }
测试用例:(dijkstra.txt)
4
0 2 -1 4
2 0 3 -1
-1 3 0 2
4 -1 2 0
1 3
make it simple, make it happen