POJ 1847 最短路问题 dijkstra算法的实现

首先自己练习了一下实现dijkstra算法,可以把dj算法与prim算法对比记忆,要理解pre数组、min数组、V标记数组的含义!

//单源最短路径,dijkstra算法,邻接阵形式,复杂度O(n^2) //求出源s到所有点的最短路经,传入图的顶点数n,(有向)邻接矩阵mat //返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1 //可更改路权类型,但必须非负! //可以把dj算法与prim算法对比记忆,要理解pre数组、min数组、V标记数组的含义! #include <iostream> #define MAXN 200 #define inf 1000000000 typedef int elem_t; using namespace std; int N,M,ss,ee,ww,s,mat[MAXN][MAXN],min[MAXN],pre[MAXN]; int i,j; //输出最短路径 void prn_pass(int k){ if (pre[pre[k]]!=-1) { cout<<"<--"<<pre[k]; prn_pass(pre[k]); } } void dijkstra(int n,elem_t mat[][MAXN],int s,elem_t* min,int* pre){ int v[MAXN],i,j,k; for (i=0;i<n;i++) min[i]=inf,v[i]=0,pre[i]=-1; for (min[s]=0,j=0;j<n;j++){ for (k=-1,i=0;i<n;i++) if (!v[i]&&(k==-1||min[i]<min[k])) k=i; for (v[k]=1,i=0;i<n;i++) if (!v[i]&&min[k]+mat[k][i]<min[i]) min[i]=min[k]+mat[pre[i]=k][i]; } } int main(){ cout<<"请输入顶点数量和边数"<<endl; cin>>N>>M; for (i = 0;i < N;i++) for (j = 0;j < N;j++) { if (i == j) mat[i][j] = 0; else mat[i][j] = inf; } cout<<"请输入各边起点终点和权值"<<endl; for (i = 0; i < M;i++) { cin>>ss>>ee>>ww; mat[ss][ee] = ww; } cout<<"请输入源点"<<endl; cin>>s; dijkstra(N,mat,s,min,pre); for (i = 0;i < N;i ++) { if (i != s) { cout<<s<<"到"<<i<<"的最短路径长度为:"<<min[i]<<endl; cout<<"路径为:"<<i; prn_pass(i); cout<<"<--"<<s<<endl; } } return 0; }

从网上看到某大牛用Floyd算法的思想也得以解决

#include <iostream> using namespace std; int A[101][101]; //Floyd算法思想 int main(){ int a,b; int N,i,j,k,x; scanf("%d%d%d",&N,&a,&b); for(i = 0;i <= N;i++) for (j = 0;j <= N;j++) { A[i][j] = 100; } for (i = 1;i <= N;i++) { cin>>k; for (j = 0;j < k; j ++)//与第i的站相连接的有k个站,赋值为1 { cin>>x; if ( j == 0 ) A[i][x] = 0; else A[i][x] = 1; } } for (k = 1;k <= N;k++) for(i = 1;i <= N;i++) for (j = 1;j <= N;j++) { if (A[i][j]>A[i][k] + A[k][j]) { A[i][j] = A[i][k] + A[k][j]; } } if (A[a][b] < A[0][0]) cout<<A[a][b]<<endl; else cout<<"-1"<<endl; return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值