http://acm.hdu.edu.cn/showproblem.php?pid=2544
flody算法代码如下:
//就是求单源最短路径用flody算法 #include<stdio.h> #include<string.h> #define M 101 int mat[M][M]; int n, m; void flody()//算法主体 { int i, j, k; for(k=1; k<=n; k++) for(i=1; i<=n; i++) for(j=1; j<=n; j++) if(mat[i][k] + mat[k][j] < mat[i][j]) mat[i][j] = mat[i][k] + mat[k][j]; } int main() { // freopen("in.txt","r",stdin); int i, a, b, c, j; while(scanf("%d %d",&n, &m)) { if(n==0 && m==0) break; for(i=1; i<=n; i++) for(j=1; j<=n; j++)//初始化为最大值 { if(i!=j) mat[i][j] = 1<<20; else mat[i][j] = 0; } for(i=0; i<m; i++) { scanf("%d %d %d",&a, &b, &c); mat[a][b] = mat[b][a] = c; } flody(); printf("%d/n",mat[1][n]); } return 0; }
dijkstra算法如下:
//用DIJKSTRA算法 #include<stdio.h> #include<string.h> #define M 101 #define inf 10000000 int d[M], mat[M][M]; bool v[M]; int n, m; void dijkstra() { int i, j, min, k; memset(v,0,sizeof(v)); for(i=1; i<=n; i++) d[i] = mat[1][i]; v[1] = true; for(i=1; i<n; i++) { min = inf; for(j=2; j<=n; j++)//找最小值 { if(!v[j] && d[j] < min) { min = d[j]; k = j; } } v[k] = true; for(j=1; j<=n; j++) if(!v[j] && mat[k][j] + d[k] < d[j])//更新与最小值相连的边 d[j] = d[k] + mat[k][j]; } } int main() { // freopen("in.txt","r",stdin); int i, j, a, b, c; while(scanf("%d %d",&n, &m)) { if(n==0 && m==0) break; for(i=1; i<=n; i++) for(j=1; j<=n; j++) { if(i!=j) mat[i][j] = inf; else mat[i][j] = 0; } for(i=0; i<m; i++) { scanf("%d %d %d",&a, &b, &c); mat[a][b] = mat[b][a] = c; } dijkstra(); printf("%d/n",d[n]); } return 0; }
fullman_ford算法如下:
//bellman-ford算法此算法适用于存在负权路径存在的情况 #include<stdio.h> #include<string.h> #define M 10001 #define N 101 #define inf 1000000000 struct node { int from, to, w; }edge[2*M]; int d[N]; int n, m; void bellman_ford() { int i, j; for(i=1; i<=n; i++) d[i] = inf; d[1] = 0; for(i=1; i<n; i++) for(j=0; j<2*m; j++) { if(d[edge[j].from] + edge[j].w < d[edge[j].to]) d[edge[j].to] = d[edge[j].from] + edge[j].w; // printf("%d %d %d %d %d/n",edge[j].from,edge[j].to,d[edge[j].from],d[edge[j].to],edge[j].w); } // for(i=0; i<2*m; i++) // if(d[edge[j].from] + edge[j].w < d[edge[j].to])//存在负权路径 // return false; // return true; } int main() { // freopen("in.txt","r",stdin); int i, a, b, c; while(scanf("%d %d",&n, &m)) { if(n==0 && m==0) break; for(i=0; i<m; i++) { scanf("%d %d %d",&a, &b, &c); edge[i].from = a; edge[i].to = b; edge[i].w = c; edge[i+m].from = b; edge[i+m].to = a; edge[i+m].w = c; } bellman_ford(); // if(bellman_ford()) printf("%d/n",d[n]); } return 0; }
SPFA算法如下:
//SPFA算法 #include<stdio.h> #include<string.h> #define inf 100000000 #define MAXM 101 int mat[MAXM][MAXM], d[MAXM]; bool v[MAXM]; int q[MAXM]; int n, m; void spfa() { int i, k, head, tail; memset(v,0,sizeof(v)); for(i=1; i<=n; i++) d[i] = inf; d[1] = 0; v[1] = true; q[1] = 1; head = tail = 1; while(head<=tail) { k = q[(head-1)%n+1]; v[k] = true; for(i=1; i<=n; i++) { if(d[i] > d[k] + mat[k][i]) { d[i] = d[k] + mat[k][i]; if(!v[i]) { v[i] = true; tail++; q[(tail-1)%n+1] = i; } } } head++; v[k] = false; } } int main() { // freopen("in.txt","r",stdin); int i, a, b, c, j; while(scanf("%d %d",&n, &m)) { if(n==0 && m==0) break; for(i=1; i<=n; i++) for(j=1; j<=n; j++) { if(i!=j) mat[i][j] = inf; else mat[i][j] = 0; } for(i=0; i<m; i++) { scanf("%d %d %d",&a, &b, &c); mat[a][b] = c; mat[b][a] = c; } spfa(); printf("%d/n",d[n]); } return 0; }
四种算法的比较(时间复杂度跟空间复杂度)