题目概述:
给一些地名和他们之间的距离,求两地点间的最短路
方法:
Dijkstra算法
1. 用map在地名字符串和integer之间产生一个映
2. 构建邻接表G并记录每一顶点周围的边
3. 利用Dijkstra算法,求单源最短路
4. 优先级队列(堆)优化
#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN = 205; // 顶点数
const int INF = 1000000; // 无穷大
int dist[MAXN];
int n;//结点数量
struct edge//建立边的结构体
{
int u;
int v;
int w;
edge(int u,int v,int w)
{
this->u= u;
this->v=v;
this->w=w;
}
};
class cmp //优先队列是默认大元素先出队 ,用 cmp实现最小先出
{
public:
bool operator()( const pair<int,int> &n1, const pair<int,int> & n2) const
{
return n1.first>n2.first;
}
};
int dijkstra(int st,int ed,vector<edge> *G)
{
priority_queue<pair<int,int>,vector<pair<int,int> >,cmp> q; //优先队列是默认大元素先出队 ,用 cmp实现最小先出
for(int i = 0;i < n;++i)
dist[i] = (i == st ? 0 : INF);//初始化dist
q.push(make_pair(dist[st],st));
while(!q.empty())
{
pair<int,int> p1 = q.top();
q.pop();
int x = p1.second;
if(p1.first != dist[x]) continue;
for(int i = 0;i < G[x].size();++i)
{
int y = G[x][i].v;
int w = G[x][i].w;
if(dist[y] > dist[x] + w) //判断是否要压入优先队列
{
dist[y] = dist[x] + w;
q.push(make_pair(dist[y],y));
}
}
}
if(dist[ed] == INF)
return -1;
else return dist[ed];
}
int main() //初始化vector<edge> G[max]
{
int t,w; // w is the weight 权重
string start,end;
cin >> t;
while(t--)
{
n = 0;//初始化结点数目
int roads;
cin >>roads;
map<string,int> M; //*/
vector<edge> G[MAXN];//邻接表 每一个顶点周围的边
for(int i = 0;i < roads;++i)
{
cin >>start >>end >> w;//输入点1,点2,权值
if(!M.count(start))
M.insert(make_pair(start,n++));
if(!M.count(end))
M.insert(make_pair(end,n++));//利用map关联容器为字符串型的边进行标号
edge E1(M[start],M[end],w);//初始化边,必须调换结点才能插入vector邻接表
edge E2(M[end],M[start],w);
G[M[start]].push_back(E1);//建立邻接表
G[M[end]].push_back(E2);
}
cin >> start >> end;
if(start == end)
cout << 0 << endl;
else if(!M.count(start) || !M.count(end))
cout << -1 << endl;
else
cout << dijkstra(M[start],M[end],G) << endl; // */
}
return 0;
}