[wikioi]回家

http://wikioi.com/problem/1079/

单源最短路径,可以用dijkstra来做。这里采用了heap优化,复杂度是(V+E)logV。这里用了STL的优先队列(堆),重复加入pair没有问题,因为dist小的会先出来。为了避免重复扩展,用了visit判重,这个也不是必须的。
注意的是:
1.pair使用的时候,把距离放在first的位置,那么在priority queue里,距离小的会先出来。
2.priority_queue<pp, vector<pp>, greater<pp> > que;这样定义,小的先出来。
3.使用graph[from][to] ?来判断是否用from=>to这条路。

#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <utility>
#include <climits>
#include <functional>
using namespace std;

#define pp pair<int, char>
 
int main()
{
    int n;
    cin >> n;
    map<char, map<char, int> > graph; // 'A'-'Z', 'a'-'z'
    map<char, int> dist;
    set<char> visit;
    for (int i = 0; i < n; i++) {
        char from, to;
        int weight;
        cin >> from >> to >> weight;
        graph[from][to] = min(weight, graph[from][to] ? graph[from][to]: INT_MAX);
        graph[to][from] = min(weight, graph[to][from] ? graph[to][from]: INT_MAX);
    }
    
    int ans = INT_MAX;
    char ansc;
    priority_queue<pp, vector<pp>, greater<pp> > que;
    dist['Z'] = 0;
    que.push(pp(0, 'Z'));
    
    while (!que.empty()) {
        pp edge = que.top();
        que.pop();
        int weight = edge.first;
        char node = edge.second;
        if (visit.count(node) != 0) continue;
        visit.insert(node);
        for (map<char,int>::iterator it = graph[node].begin();
            it != graph[node].end(); it++) {
            if (!dist.count(it->first) ||
                    it->second + dist[node] < dist[it->first]) {
                // add to que
                dist[it->first] = it->second + dist[node];
                que.push(pp(dist[it->first], it->first));
                if (ans > dist[it->first] && it->first >= 'A' && it->first < 'Z') {
                    ans = dist[it->first];
                    ansc = it->first;
                }
            }
        }
    }
    
    cout << ansc << " " << ans << endl;
    return 0;
}

  

 

posted @ 2013-10-27 17:54  阿牧遥  阅读(219)  评论(0)    收藏  举报