ACM-ICPC 2018 沈阳赛区网络预赛 D Made In Heaven (k短路 :最短路 + 可持续化堆/A*)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cys460714380/article/details/82534180

https://nanti.jisuanke.com/t/31445

可持续化堆

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef bool boolean;

#define pii pair<int, int>
#define fi first
#define sc second

typedef class Node {
public:
    int val, ed;
    Node *l, *r;

    Node()    {        }
    Node(int val, int ed, Node *l, Node *r):val(val), ed(ed), l(l), r(r) {        }
} Node;

#define Limit 1000000

Node pool[Limit];
Node* top = pool;

Node* newnode(int val, int ed) {
    if(top >= pool + Limit)
        return new Node(val, ed, NULL, NULL);
    top->val = val, top->ed = ed, top->l = top->r = NULL;
    return top++;
}

Node* merge(Node* a, Node* b) {
    if (!a)    return b;
    if (!b)    return a;
    if (a->val > b->val)    swap(a, b);
    Node* p = newnode(a->val, a->ed);
    p->l = a->l, p->r = a->r;
    p->r = merge(p->r, b);
    swap(p->l, p->r);
    return p;
}

typedef class Status {
public:
    int dist;
    Node* p;

    Status(int dist = 0, Node* p = NULL):dist(dist), p(p) {        }

    boolean operator < (Status b) const {
        return dist > b.dist;
    }
} Status;

typedef class Edge {
public:
    int end, next, w;

    Edge(int end = 0, int next = 0, int w = 0):end(end), next(next), w(w) {        }
} Edge;

typedef class MapManager {
public:
    int ce;
    int* h;
    Edge* es;

    MapManager() {            }
    MapManager(int n, int m):ce(0) {
        h = new int[(n + 1)];
        es = new Edge[(m + 5)];
        memset(h, 0, sizeof(int) * (n + 1));
    }

    void addEdge(int u, int v, int w) {
        es[++ce] = Edge(v, h[u], w);
        h[u] = ce;
    }

    Edge& operator [] (int pos) {
        return es[pos];
    }
} MapManager;

int n, m;
int s, t, k,mxt;
MapManager g;
MapManager rg;
boolean *vis;
int* f, *lase;

inline bool init() {
    if(scanf("%d%d", &n, &m)==-1)return 0;
    g = MapManager(n, m);
    rg = MapManager(n, m);
    scanf("%d%d%d%d", &s, &t, &k,&mxt);
    for (int i = 1, u, v, w; i <= m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        g.addEdge(u, v, w);
        rg.addEdge(v, u, w);
    }
    return 1;
}

queue<int> que;
void spfa(MapManager& g, int s) {
    vis = new boolean[(n + 1)];
    f = new int[(n + 1)];
    lase = new int[(n + 1)];
    memset(f, 0x7f, sizeof(int) * (n + 1));
    memset(vis, false, sizeof(boolean) * (n + 1));
    que.push(s);
    f[s] = 0, lase[s] = 0;
    while (!que.empty()) {
        int e = que.front();
        que.pop();
        vis[e] = false;
        for (int i = g.h[e]; i; i = g[i].next) {
            int eu = g[i].end, w = g[i].w;
            if (f[e] + w < f[eu]) {
                f[eu] = f[e] + w, lase[eu] = i;
                if (!vis[eu]) {
                    vis[eu] = true;
                    que.push(eu);
                }
            }
        }
    }
}

Node** hs;
inline void rebuild() {
    for (int i = 1; i <= n; i++)
        for (int j = g.h[i]; j; j = g[j].next) {
            int e = g[j].end;
            if (lase[i] != j)
                g[j].w += f[e] - f[i];
        }

    hs = new Node*[(n + 1)];
    que.push(t);
    hs[t] = NULL;
    while (!que.empty()) {
        int e = que.front();
        que.pop();
        if (lase[e])
            hs[e] = hs[g[lase[e]].end];
        for (int i = g.h[e]; i; i = g[i].next)
            if (lase[e] != i && f[g[i].end] != 0x7f7f7f7f)
                hs[e] = merge(hs[e], new Node(g[i].w, g[i].end, NULL, NULL));
        for (int i = rg.h[e]; i; i = rg[i].next) {
            int eu = rg[i].end;
            if (lase[eu] == i)
                que.push(eu);
        }
    }
}
int inf = 0x3f3f3f3f;
inline int kthpath(int k) {
    if (s == t)
        k++;
    if (f[s] == 0x7f7f7f7f)
        return inf;
    if (k == 1)
        return f[s];

    priority_queue<Status> q;
    if (!hs[s])
        return inf;

    q.push(Status(hs[s]->val, hs[s]));
    while (--k && !q.empty()) {
        Status e = q.top();
        q.pop();

        if(k == 1)
            return e.dist + f[s];
        if(e.dist+f[s]>mxt)return inf;
        int eu = e.p->ed;
        if (hs[eu])
            q.push(Status(e.dist + hs[eu]->val, hs[eu]));
        if (e.p->l)
            q.push(Status(e.dist - e.p->val + e.p->l->val, e.p->l));
        if (e.p->r)
            q.push(Status(e.dist - e.p->val + e.p->r->val, e.p->r));
    }
    return inf;
}

inline int solve() {
    return kthpath(k);
}

int main() {
    for(; init();) {
        spfa(rg, t);
        rebuild();
        int ck = solve();
        if(ck<=mxt)puts("yareyaredawa");
        else puts("Whitesnake!");
    }

    return 0;
}

A*

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define rep(i,a,n) for(int i=(a);i<(n);++i)
#define per(i,a,n) for(int i=(n)-1;i>=(a);--i)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second

typedef pair<int, int> pii;
#define mp(a,b) make_pair(a,b)
const int N = 100005;
vector<pii> e[N], re[N];
int n, m, k, T, s, t;
bool vis[N];
int dis[N];
struct node {
    int v, v1, v2;
    bool operator<(const node &rhs) const {
        if (v1 == rhs.v1) return v2 > rhs.v2;
        return v1 > rhs.v1;
    }
};

inline int A_st() {
    int cnt = 0;
    if(s == t) k++;
    if(dis[s] > T) return T + 1;
    priority_queue<node> pq;
    pq.push((node){s, dis[s], 0});
    while(!pq.empty()) {
        node cur = pq.top();
        pq.pop();
        if(cur.v == t) cnt++;
        if(cnt == k) {
            return cur.v2;
        }
        int sz = re[cur.v].size();
        for(int j=0;j<sz;++j) {
            pii eg = re[cur.v][j];
            node nxt;
            nxt.v = eg.first;
            nxt.v2 = cur.v2 + eg.second;
            nxt.v1 = nxt.v2 + dis[nxt.v];
            pq.push(nxt);
        }
    }
    return T + 1;
}
int main() {
    while (~scanf("%d%d",&n,&m)) {
        scanf("%d%d",&s,&t);scanf("%d%d",&k,&T);
        for (int i = 0; i <= n; ++i) {
            e[i].clear();re[i].clear();
            vis[i] = 0;dis[i] = 0x3f3f3f3f;
        }
        for(int i=0;i<m;++i){
            int u, v, w;
            scanf("%d%d%d",&u,&v,&w);
            re[u].push_back(mp(v, w));
            e[v].push_back(mp(u, w));
        }
        priority_queue<pii> q;
        q.push(mp(dis[t] = 0, t));
        while (!q.empty()) {
            int u = q.top().second;q.pop();
            if (vis[u]) continue;
            vis[u] = 1;
            int sz = e[u].size();
            for (int j=0;j<sz;++j) {
                pii eg = e[u][j];
                int v = eg.first, w = eg.second;
                if (dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    q.push(mp(-dis[v], v));
                }
            }
        }
        int t = A_st();
        puts(t <= T ? "yareyaredawa" : "Whitesnake!");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/cys460714380/article/details/82534180