zoukankan      html  css  js  c++  java
  • [SDOI 2010]魔法猪学院

    Description

    题库链接

    给出一张 (n) 个点 (m) 条边有向图,询问最多有多少条不同的路径从 (1)(n) 并且路径长度和 (leq E)

    (2leq nleq 5000,1leq mleq 200000,1leq Eleq 10^7)

    Solution

    由于要求最多多少条,我们有贪心的思想,选取尽可能短的路径不会差。

    那么题目就变成了求这张图 (1 ightarrow n) 的最短的 (ans) 条路径,并且路径的长度和 (leq E)

    就变成了裸的 (k) 短路问题。

    (f(x)=g(x)+h(x)) ,由于让路径尽可能短,那么估价函数 (h(x)) 就取点 (x)(n) 的最短路就好了。

    b站上这道题代码写的丑的 (stl)(MLE) ,像我这种菜鸡肯定过不了,只能手写可并堆了...

    Code

    //It is made by Awson on 2018.3.1
    #include <bits/stdc++.h>
    #define LL long long
    #define dob complex<double>
    #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
    #define writeln(x) (write(x), putchar('
    '))
    #define lowbit(x) ((x)&(-(x)))
    using namespace std;
    const int N = 5000, M = 200000, INF = ~0u>>1;
    void read(int &x) {
        char ch; bool flag = 0;
        for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
        for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
        x *= 1-2*flag;
    }
    void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
    void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
    
    int n, m, vis[N+5]; double dist[N+5], e;
    struct node {
        double f, g; int u;
        bool operator < (const node &b) const {return f > b.f; }
    };
    struct mergeable_tree {
        int ch[1300005][2], dist[1300005], pos, root, cnt; node k[1300005];
        queue<int>mem;
        int newnode(node x) {
        int o; if (!mem.empty()) o = mem.front(), mem.pop(); else o = ++pos;
        ch[o][0] = ch[o][1] = dist[o] = 0; k[o] = x; return o;
        }
        int merge(int a, int b) {
        if (!a || !b) return a+b;
        if (k[a] < k[b]) Swap(a, b);
        ch[a][1] = merge(ch[a][1], b);
        if (dist[ch[a][0]] < dist[ch[a][1]]) Swap(ch[a][0], ch[a][1]);
        dist[a] = dist[ch[a][1]]+1; return a;
        }
        node top() {return k[root]; }
        void push(node x) {root = merge(root, newnode(x)); ++cnt; }
        void pop() {mem.push(root); root = merge(ch[root][0], ch[root][1]); --cnt; }
        bool empty() {return !cnt; }
    }Q;
    struct Graph {
        struct tt {int to, next; double cost; }edge[M+5];
        int path[N+5], top;
        void add(int u, int v, double c) {edge[++top].to = v, edge[top].next = path[u], edge[top].cost = c, path[u] = top; }
        void SPFA() {
        for (int i = 1; i < n; i++) dist[i] = INF;
        queue<int>Q; vis[n] = 1; Q.push(n);
        while (!Q.empty()) {
            int u = Q.front(); Q.pop(); vis[u] = 0;
            for (int i = path[u]; i; i = edge[i].next)
            if (dist[edge[i].to] > dist[u]+edge[i].cost) {
                dist[edge[i].to] = dist[u]+edge[i].cost;
                if (!vis[edge[i].to]) Q.push(edge[i].to), vis[edge[i].to] = 1;
            }
        }
        }
        int Astar() {
        int ans = 0;
        node t, tt; t.f = dist[1], t.g = 0, t.u = 1;
        Q.push(t);
        while (!Q.empty()) {
            t = Q.top(); Q.pop();
            if (t.u == n) {if (e >= t.f) {ans++, e -= t.f; continue; } else break; }
            for (int i = path[t.u]; i; i = edge[i].next) {
            tt.g = t.g+edge[i].cost, tt.u = edge[i].to, tt.f = tt.g+dist[edge[i].to];
            Q.push(tt);
            }
        }
        return ans;
        }
    }g1, g2;
    
    void work() {
        read(n), read(m); scanf("%lf", &e); int u, v; double c;
        for (int i = 1; i <= m; i++) {
        read(u), read(v), scanf("%lf", &c), g1.add(u, v, c), g2.add(v, u, c);
        }
        g2.SPFA(); writeln(g1.Astar());
    }
    int main() {
        work(); return 0;
    }
  • 相关阅读:
    CF1539 VP 记录
    CF1529 VP 记录
    CF875C National Property 题解
    CF1545 比赛记录
    CF 1550 比赛记录
    CF1539E Game with Cards 题解
    CF1202F You Are Given Some Letters... 题解
    vmware Linux虚拟机挂载共享文件夹
    利用SOLR搭建企业搜索平台 之九(solr的查询语法)
    利用SOLR搭建企业搜索平台 之四(MultiCore)
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8486667.html
Copyright © 2011-2022 走看看