基于Dijsktra算法的最短路径求解:
问题描述:一张地图包括n个城市,假设城市间有m条路径(有向图),每条路径的长度已知。给定地图的一个起点城市和终点城市,利用Dijsktra算法求出起点到终点之间的最短路径。
输入要求:
多组数据,每组数据有m+3行。第一行为两个整数n和m,分别代表城市个数n和路径条数m。第二行有n个字符,代表每个城市的名字。第三行到第m+2行每行有两个字符a和b和一个整数d,代表从城市a到城市b有一条距离为d的路。最后一行为两个字符,代表待求最短路径的城市起点和终点。当n和m都等于0时,输入结束。
输出要求:
每组数据输出两行。第一行为一个整数,为从起点到终点之间最短路的长度。第二行为一串字符串,代表该路径。每两个字符之间用空格隔开。
输入样例
3 3
A B C
A B 1
B C 1
C A 3
A C
输出样例
2
A B C
代码实现
#include <iostream>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int MAX = 1e6+100;
char x,y;
map<char,int> mp;
map<int,char> mpp;
struct hh{
int u,v,w,nt;
hh(){}
hh(int ww,int vv){
w=ww;
v=vv;
}
bool operator<(const hh &q) const{
return w>q.w;
}
}a[MAX];
int tot,head[MAX],dis[MAX],bian[MAX];
void add(int u,int v,int w){
a[tot].u=u;
a[tot].v=v;
a[tot].w=w;
a[tot].nt=head[u];
head[u]=tot++;
}
void init(){
memset(head,-1,sizeof(head));
memset(dis,inf,sizeof(dis));
memset(bian,0,sizeof(bian));
}
void print(int v){
if(bian[v]==0){
cout << mpp[v] << " ";
return;
}
print(bian[v]);
cout << mpp[v] << " ";
return;
}
void dij(int s){
priority_queue<hh> q;
dis[s]=0;
q.push(hh(dis[s],s));
while(!q.empty()){
hh tmp;
tmp=q.top();
q.pop();
int u=tmp.v;
if(u==mp[y]) break;
for (int i = head[u]; ~i;i=a[i].nt){
int v=a[i].v;
if(dis[v]>dis[u]+a[i].w){
dis[v]=dis[u]+a[i].w;
bian[v]=u;
q.push(hh(dis[v],v));
}
}
}
}
int main(){
int n,m;
while(cin >> n >> m){
if(n==0&&m==0) break;
init();
mp.clear();
mpp.clear();
int cnt=1;
for (int i = 0; i < n;i++){
char ch;
cin >> ch;
mp[ch]=cnt;
mpp[cnt++]=ch;
}
for (int i = 0; i < m;i++){
char u,v;
int w;
cin >> u >> v >> w;
add(mp[u],mp[v],w);
add(mp[v],mp[u],w);
}
cin >> x >> y;
dij(mp[x]);
cout << dis[mp[y]] << endl;
print(mp[y]);
cout << endl;
}
return 0;
}