相关链接:
题目链接:HDU - 2544
优先队列
这是一道迪杰斯特拉的一道模板题
迪杰斯特拉的做法是从源点出发,找到与该点相连的所有点,选择一条最短的路连接
再从连接的这个点出发,再找与这个点相连的点的最短的路
重复上述做法,直到找到距离最短路
以下AC代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef pair<int,int> P;
const int INF =0x3f3f3f3f;
const int MAXN = 105;
int n,m;
int mp[MAXN][MAXN],dis[MAXN];
bool vis[MAXN];
void init(){
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) mp[i][j]=0;
else mp[i][j]=INF;
}
}
}
void dijkstra(){
dis[1]=0;
priority_queue<P,vector<P>,greater<P> >que;
que.push(P(dis[1],1));
while(!que.empty()){
P p = que.top();
que.pop();
int k = p.second;
vis[k]=1;
for(int i=1;i<=n;i++){
if(dis[i]>mp[k][i]+dis[k]&&!vis[i]){
dis[i]=mp[k][i]+dis[k];
que.push(P(dis[i],i));
}
}
}
printf("%d\n",dis[n]);
}
int main(){
int a,b,d;
while(scanf("%d%d",&n,&m),n||m){
init();
for(int i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&d);
if(mp[a][b]>d){
mp[a][b]=d;
mp[b][a]=d;
}
}
dijkstra();
}
return 0;
}
我们单独对上面写的dijkstra()进行分析
void dijkstra(){
dis[1]=0;
priority_queue<P,vector<P>,greater<P> >que;
que.push(P(dis[1],1));
while(!que.empty()){
P p = que.top();
que.pop();
int k = p.second;
vis[k]=1;
for(int i=1;i<=n;i++){
if(dis[i]>mp[k][i]+dis[k]&&!vis[i]){
dis[i]=mp[k][i]+dis[k];
que.push(P(dis[i],i));
}
}
}
函数中优先队列的作用是对距离进行排序,保证距离最短的边在前面,遍历的时候也是从最小的边开始找的
还有就是为什么要用pair<>,它的作用是为了方便获取距离dis[]的下标,出队就表示这个点已经纳入到最短路径当中了
for(int i=1;i<=n;i++){
if(dis[i]>mp[k][i]+dis[k]&&!vis[i]){
dis[i]=mp[k][i]+dis[k];
que.push(P(dis[i],i));
}
}
这段代码对应于找与这个点相连的各点的最短的距离