zoukankan      html  css  js  c++  java
  • SPOJ #440. The Turtle´s Shortest Path

    Coding a Dijkstra is not hard. %70 of my time spent on tackling TLE, as my last post.

    Dijkstra works in BFS manner, but at each step, it picks the shortest child greedily and then relax all other neighbors. 

    Data Structure: since there could be up to 10000 cities, storing distance for all pairs of cities are not allowed - 300+M space exceeds SPOJ's 256M limit. So I simply used std::map (my another version used GNU's hash_map but not tried its performance) as the adjacent linked list to store graph; and map<string, int> to store city name - index mapping. Again, hash_map could be better.

    Anyway, here's my AC code, 11.34s:

    //    440
    
    #include <vector>
    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <map>
    using namespace std;
    
    /*
    //////////////////////////////////
    //    Components for GNU's hash_map
    #include <backward/hash_map>
    using namespace __gnu_cxx;
    namespace __gnu_cxx
    {
      template<>
      struct hash<std::string>
      {
        hash<char*> h;
        size_t operator()(const std::string &s) const
        {
          return h(s.c_str());
        };
      };
    }
    */
    //////////////////////////////////
    
    const int MaxCity = 10000;
    const int MaxDist = 0xFFFFFFF;
    map<string, int> hmap;
    typedef map<int, map<int, int> > DHash;
    DHash distMap;
    
    bool visited[MaxCity] = {false};
    int dist[MaxCity] = {MaxDist};
    
    /////////////////////////////////////
    void add_dist(int srcInx, int toInx, int cost)
    {
        distMap[srcInx][toInx] = cost;
    }
    int get_dist(int srcInx, int toInx)
    {
        DHash::iterator iter = distMap.find(srcInx);
        if(iter != distMap.end())
        {
            map<int, int>::iterator iter2 = iter->second.find(toInx);
            if(iter2 != iter->second.end())
            {
                return iter2->second;
            }
        }
        return MaxDist;
    }
    /////////////////////////////////////
    struct nComp
    {
     int operator() (const pair<int,int>& p1, const pair<int,int> &p2)
     {
         return p1.second > p2.second;
     }
    };
    ///////////////////////////////////////
    void clearGraph()
    {
        hmap.clear();
        distMap.clear();
    }
    
    void clearRuntime(int citycnt)
    {
        for(int i = 0; i < citycnt; i ++)
        {
            visited[i] = false;
            dist[i] = MaxDist;
        }
    }
    ///////////////////////////////////////////
    int find_shortest_path(int cinx1, int cinx2)
    {
        int vcnt = hmap.size();
    
        priority_queue<pair<int, int>, vector<pair<int, int> >, nComp> q;
        //    Init
        for(int i = 0; i < vcnt; i ++)
        {
            dist[i] = MaxDist;
            visited[i] = false;
        }
        dist[cinx1 - 1] = 0;
        q.push(make_pair(cinx1-1, 0));
    
        //    Go
        while(!q.empty())
        {
            pair<int,int> n = q.top(); q.pop();
    
            //    Greedy, find the unvisited min-cost node
            int minInx = n.first;
            int minCost = n.second;
            if(minCost == MaxDist)    break;
            visited[minInx] = true;
            if(minInx == cinx2 - 1) return dist[cinx2 - 1];
    
            //    Relax neighbors
            DHash::iterator iter = distMap.find(minInx);
            map<int,int> &child = iter->second;
            for(map<int,int>::iterator iMap = child.begin(); iMap != child.end(); iMap ++)
            {
                int i = iMap->first;
                int gDist = iMap->second;
                int alt = dist[minInx] + gDist;
                if(alt < dist[i])
                {
                    dist[i] = alt;
                    //cout << "		relaxed to " << alt << " " << minInx << " to" << i <<endl;
                    q.push(make_pair(i, dist[i]));
                }
            }
        }
    
        return MaxDist;
    }
    /////////////////////////
    #define gc getchar
    int read_int()
    {
      char c = gc();
      while(c<'0' || c>'9') c = gc();
      int ret = 0;
      while(c>='0' && c<='9') {
        ret = 10 * ret + c - 48;
        c = gc();
      }
      return ret;
    }
    /////////////////////////
    int main()
    {
        int runcnt = read_int();
        //cout << "Run " << runcnt << endl;
        while(runcnt --)
        {
            clearGraph();
            int ccnt = read_int();
            for(int ic = 1; ic <= ccnt; ic ++)
            {
                // cityName -> cityInx
                string city_name; cin >> city_name;
                int nnbr = read_int();
                hmap.insert(map<string, int>::value_type(city_name, ic));
                //cout << city_name << "->" << ic << endl;
    
                //    Fill out adjacency matrix
                while(nnbr--)
                {
                    int cinx = read_int();
                    int cost = read_int();
                    add_dist(ic-1, cinx-1, cost);
                    //cout << ic << " <-> " << cinx << " = " << cost << endl;
                }
            }
    
            int qcnt  = read_int();
            while(qcnt --)
            {
                string c1, c2;
                cin >> c1 >> c2;
                int cinx1 = hmap[c1];
                int cinx2 = hmap[c2];
            //    cout << c1 << "-" << c2 << " = " << cinx1 << " - " << cinx2 << endl;
                clearRuntime(ccnt);
                cout << find_shortest_path(cinx1, cinx2) << endl;
            }
            getchar();
            getchar(); // should return 0xA (enter)
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    MySQL Online DDL导致全局锁表案例分析
    .NET Core教程--给API加一个服务端缓存啦
    任务队列和异步接口的正确打开方式(.NET Core版本)
    .NET Core中使用RabbitMQ正确方式
    .NET Core单元测试之搞死开发的覆盖率统计(coverlet + ReportGenerator )
    没有执行过rm -rf /*的开发不是好运维
    dotnet core在Task中使用依赖注入的Service/EFContext
    可能是全网首个支持阿里云Elasticsearch Xapck鉴权的Skywalking
    dpdk中QSBR具体实现
    C语言二级指针底层实现
  • 原文地址:https://www.cnblogs.com/tonix/p/3548072.html
Copyright © 2011-2022 走看看