zoukankan      html  css  js  c++  java
  • PAT 1030 Travel Plan

    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <unordered_map>
    #include <algorithm>
    #include <climits>
    
    #define CMB(ID1, ID2) (((ID1)<<9) | (ID2))
    
    using namespace std;
    
    class City {
    public:
        vector<int> adj;
        int dist;
        City(int d = INT_MAX): dist(d){}
    };
    
    typedef pair<int, int> P;
    
    // sparse table
    unordered_map<int, int> dist;
    unordered_map<int, int> cost;
    
    void print_cities(vector<City> &cities) {
        int len = cities.size();
        
        for (int i=0; i<len; i++) {
            printf("%d
    ", i);
            int adj_len = cities[i].adj.size();
            for (int j=0; j<adj_len; j++) {
                int cid = CMB(i, cities[i].adj[j]);
                printf("	%d %d %d", cities[i].adj[j], dist[cid], cost[cid]);
            }
            printf("
    ");
        }
    }
    
    void dfs(vector<int> &final, vector<int>& path, int path_cost, int &final_cost, vector<City>& cities, int idx) {
            if (cities[idx].dist == 0) {
                // we reach the start point
                if (path_cost < final_cost) {
                    final_cost = path_cost;
                    final = path;
                    final.push_back(idx);
                }
                return;
            }
            City& cur_city = cities[idx];
            int adj_len = cur_city.adj.size();
            
            for (int i=0; i<adj_len; i++) {
                int adj_idx = cur_city.adj[i];
                int pdist = cities[adj_idx].dist + dist[CMB(idx, adj_idx)];
                if (pdist == cur_city.dist) {
                    // adj city on the shortest path
                    path.push_back(idx);
                    path_cost += cost[CMB(idx, adj_idx)];
                    // follow it
                    dfs(final, path, path_cost, final_cost, cities, adj_idx);
                    
                    path_cost -= cost[CMB(idx, adj_idx)];
                    path.pop_back();
                }
            }
    }
    
    int main() {
        int N, M, S, D;
        scanf("%d%d%d%d", &N, &M, &S, &D);
    
        vector<City> cities(N);
    
        int c1, c2, d, c;
        
        for (int i=0; i<M; i++) {
            scanf("%d%d%d%d", &c1, &c2, &d, &c);
            dist.insert(make_pair(CMB(c1, c2), d));
            dist.insert(make_pair(CMB(c2, c1), d));
            cost.insert(make_pair(CMB(c1, c2), c));
            cost.insert(make_pair(CMB(c2, c1), c));
            cities[c1].adj.push_back(c2);
            cities[c2].adj.push_back(c1);
        }
        
        cities[S].dist = 0;
        
        //print_cities(cities);
        
        priority_queue<P, vector<P>, greater<P> > nodes;
        
        nodes.push(make_pair(0, S));
        
        bool updated = true;
        while (updated) {
            updated = false;
            P node = nodes.top();
            nodes.pop();
            int cur_idx = node.second;
            int cur_dst = node.first;
            if (cur_dst > cities[cur_idx].dist) {
                // there is another shorter path to the current selected city
                // so the node info is out of date, just drop it
                updated = true;
                continue;
            }
            
            City& cur_city = cities[cur_idx];
            int alen = cur_city.adj.size();
            
            // traverse adj cities of the current city
            for (int i=0; i<alen; i++) {
                int adj_idx = cur_city.adj[i];
                City& adj_city = cities[adj_idx];
                
                int new_dist = cur_city.dist + dist[CMB(cur_idx, adj_idx)];
                if (new_dist < adj_city.dist) {
                    adj_city.dist = new_dist;
                    nodes.push(make_pair(new_dist, adj_idx));
                    updated = true;
                }
            }
        }
        
        vector<int> final, path;
        int path_cost = 0, final_cost = INT_MAX;
        dfs(final, path, path_cost, final_cost, cities, D);
        
        int flen = final.size();
        if (flen < 1) {
            return 0;
        }
        reverse(final.begin(), final.end());
        
        printf("%d", final[0]);
        for (int i=1; i<flen; i++) {
            printf(" %d", final[i]);
        }
        printf(" %d %d", cities[D].dist, final_cost);
        return 0;
    }

    又是最短路径,好像很喜欢,有点烦

  • 相关阅读:
    SqlCacheDependency [转]
    C#导出Word [ZT]
    ADO.NET Entity Framework 学习(1) [ZT]
    AJAX, JSON.js,Newtonsoft.Json.dll,nunit.framework.dll 源代码
    ADO.NET 1.1和2.0事务的区别
    Sql Server 2000 中游标的使用示例 [ZT]
    如何检测是否安装了.NET 2.0和.NET 3.0 [ZT]
    ORACLE 常用函数 [ZT]
    Resource 学习笔记
    GridView 双击选择行 [ZT]
  • 原文地址:https://www.cnblogs.com/lailailai/p/4078366.html
Copyright © 2011-2022 走看看