HDU-6705 Path

Description

You have a directed weighted graph with n vertexes and m edges. The value of a path is the sum of the weight of the edges you passed. Note that you can pass any edge any times and every time you pass it you will gain the weight.node

Now there are q queries that you need to answer. Each of the queries is about the k-th minimum value of all the paths.c++

Input

The input consists of multiple test cases, starting with an integer t (1≤t≤100), denoting the number of the test cases.
The first line of each test case contains three positive integers n,m,q. (\(1≤n,m,q≤5∗10^4\))ui

Each of the next m lines contains three integers ui,vi,wi, indicating that the i−th edge is from ui to vi and weighted wi.(1≤ui,vi≤n,1≤wi≤109)spa

Each of the next q lines contains one integer k as mentioned above.(\(1≤k≤5∗10^4\))code

It's guaranteed that \(Σn ,Σm, Σq,Σmax(k)≤2.5∗10^5\) and max(k) won't exceed the number of paths in the graph.排序

Output

For each query, print one integer indicates the answer in line.three

Sample Input

1
2 2 2
1 2 1
2 1 2
3
4

Sample Output

3
3

題解

給定一張有向圖,q次詢問,每次詢問第k小的路徑長度。ip

離線,預處理出最大的k範圍內的全部路徑長度。先將全部邊按邊權排序,用一個set存儲當前能夠成爲答案的邊,且set的最大的大小爲maxk,每次從set中取出w最小的邊,看看可否更新set中的元素,不能更新則break(邊權從小到大排序,小邊權沒法更新以後邊權也沒法更新),對set中的元素都作一次這樣的處理後,咱們就獲得了[1,maxk]的答案,輸出詢問便可,複雜度\(O(k*log(m+k))\)input

AC代碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e4 + 50;
struct node {
    int v; ll w;
    node (int v = 0, int w = 0): v(v), w(w) {}
    bool operator < (const node &b) const {
        return w < b.w;
    }
};
vector<node> G[N];
struct Edge {
    int u, v; ll w;
    int id;
    Edge(int u = 0, int v = 0, ll w = 0, int id = 0): u(u), v(v), w(w), id(id) {}
    bool operator < (const Edge &b) const {
        if (w == b.w)
            if (u == b.u)
                if (v == b.v)
                    return id < b.id;
                else return v < b.v;
            else return u < b.u;
        else return w < b.w;
    }
    bool operator == (const Edge &b) const {
        return w == b.w && u == b.u && v == b.v && id == b.id;
    }
};
int Q[N];
ll ans[N];
int main() {
    int t; scanf("%d", &t);
    while (t--) {
        int n, m, q;
        scanf("%d%d%d", &n, &m, &q);
        for (int i = 1; i <= n; i++) G[i].clear();
        set<Edge> st; st.clear();
        int cnt = 0;
        for (int i = 1; i <= m; i++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            G[u].push_back(node(v, w));
            st.insert(Edge(u, v, w, ++cnt));
        }
        for (int i = 1; i <= n; i++) sort(G[i].begin(), G[i].end());
        int maxk = 0;
        for (int i = 1; i <= q; i++) {
            scanf("%d", &Q[i]);
            maxk = max(maxk, Q[i]);
        }
        while (st.size() > maxk) st.erase(st.end());
        for (int i = 1; i <= maxk; i++) {
            Edge now = *st.begin();
            st.erase(st.begin());
            ans[i] = now.w;
            if (i == maxk) break;
            int u = now.v;
            for (int j = 0; j < G[u].size(); j++) {
                int v = G[u][j].v;
                ll w = G[u][j].w;
                if (i + st.size() < maxk) st.insert(Edge(now.u, v, now.w + w, ++cnt));
                else {
                    set<Edge>::iterator it = st.end(); it--;
                    Edge last = *it;
                    if (now.w + w < last.w) {
                        st.erase(it);
                        st.insert(Edge(u, v, now.w + w, ++cnt));
                    }
                    else break;
                }
            }
        }
        for (int i = 1; i <= q; i++) printf("%lld\n", ans[Q[i]]);
    }
    return 0;
}
相關文章
相關標籤/搜索