sicily 1006. Campus_mothod_2(Dijkstra算法)

来源:互联网 发布:比特彗星端口设置 编辑:程序博客网 时间:2024/05/16 14:41

题目概述:

给一些地名和他们之间的距离,求两地点间的最短路

方法:

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;    }
0 0
原创粉丝点击