zoukankan      html  css  js  c++  java
  • POJ 2449 Remmarguts' Date (算竞进阶习题)

    A* + dijkstra/spfa

    第K短路的模板题,就是直接把最短路当成估价函数,保证估价函数的性质(从当前状态转移的估计值一定不大于实际值)
    我们建反图从终点跑最短路,就能求出从各个点到终点的最短距离,这样就能满足估价函数的性质了
    要注意一点,当起点和终点一样的时候第k短路就变成k+1短了,因为0也算一条。。。

    话说回来为啥我用pair就MLE了呢。。。。

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int X = 0, w = 0; char ch = 0;
        while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
        while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
        return w ? -X : X;
    }
    inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
    inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
    template<typename T>
    inline T max(T x, T y, T z){ return max(max(x, y), z); }
    template<typename T>
    inline T min(T x, T y, T z){ return min(min(x, y), z); }
    template<typename A, typename B, typename C>
    inline A fpow(A x, B p, C yql){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % yql)if(p & 1)ans = 1LL * x * ans % yql;
        return ans;
    }
    const int N = 1005;
    int n, m, k, s, t, cnt1, cnt2, head1[N], head2[N], dist[N], num[N], w[N];
    bool vis[N];
    struct Edge{ int v, next, dis; } edge1[100005], edge2[100005];
    
    struct Point{
        int s, dis;
        bool operator < (const Point &rhs) const {
            return dis > rhs.dis;
        }
        Point(int s, int dis): s(s), dis(dis){}
    };
    
    struct Node{
        int v, f, g;
        Node(int v, int f, int g): v(v), f(f), g(g){}
        bool operator < (const Node &rhs) const{
            return f + g > rhs.f + rhs.g;
        }
    };
    
    void addEdge1(int a, int b, int c){
        edge1[cnt1].v = b, edge1[cnt1].next = head1[a], edge1[cnt1].dis = c;
        head1[a] = cnt1 ++;
    }
    
    void addEdge2(int a, int b, int c){
        edge2[cnt2].v = b, edge2[cnt2].next = head2[a], edge2[cnt2].dis = c;
        head2[a] = cnt2 ++;
    }
    
    void dijkstra(){
        fill(dist, dist + N, INF);
        priority_queue<Point> pq;
        dist[t] = 0;
        pq.push(Point(t, dist[t]));
        while(!pq.empty()){
            int s = pq.top().s, d = pq.top().dis; pq.pop();
            if(vis[s]) continue;
            vis[s] = true;
            for(int i = head2[s]; i != -1; i = edge2[i].next){
                int u = edge2[i].v;
                if(dist[u] > d + edge2[i].dis){
                    dist[u] = d + edge2[i].dis;
                    pq.push(Point(u, dist[u]));
                }
            }
        }
    }
    
    int astar(){
        if(dist[s] == INF) return -1;
        if(s == t) k ++;
        priority_queue<Node> pq;
        pq.push(Node(s, dist[s], 0));
        while(!pq.empty()){
            Node cur = pq.top(); pq.pop();
            num[cur.v] ++;
            if(cur.v == t && num[cur.v] == k) return cur.f + cur.g;
            if(num[cur.v] > k) continue;
            for(int i = head1[cur.v]; i != -1; i = edge1[i].next){
                int u = edge1[i].v;
                if(num[u] == k) continue;
                pq.push(Node(u, dist[u], cur.g + edge1[i].dis));
            }
        }
        return -1;
    }
    
    void init(){
        cnt1 = cnt2 = 0;
        memset(head1, -1, sizeof head1);
        memset(head2, -1, sizeof head2);
    }
    
    int main(){
    
        while(scanf("%d%d", &n, &m) != EOF){
            init();
            for(int i = 0; i < m; i++){
                int a, b, c; scanf("%d%d%d", &a, &b, &c);
                addEdge1(a, b, c), addEdge2(b, a, c);
            }
            scanf("%d%d%d", &s, &t, &k);
            dijkstra();
            printf("%d
    ", astar());
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    高性能网站建设之 MS Sql Server数据库分区
    Sql Server 分区演练
    数据库的优化措施 索引优化
    TabHost两种不同的实现方式
    Call requires API level 7 (current min is 1):(问题解决)
    Android特效 五种Toast详解
    SQLite使用
    android下db-journal文件作用
    关于android通过shell修改文件权限的学习
    关于android写入SD卡数据的学习代码
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/10538478.html
Copyright © 2011-2022 走看看