2019CCPC network shortest qualifying 1004 path

You have to m a n points to the edges of the map, ask this all there is to the length of the road map in the short path is the number of k-: meaning of the questions? n, m, k are 5e4 level.

Ideas: Some time ago there was a div3 of F and a bit like the question, but the question asking for is the shortest and the maximum is 400 k. This approach is in fact a question of routine (not seen QAQ).

First of all the side-by-point of each edge weight from small to large, the weights of each edge point of minimum that edge in the priority queue. For each point priority queue record at this point is the transfer point from which come (last), transferred from the side for the last is the first of several small (rank). In this case, the minimum from the current point now selected the right side of an edge, into the queue to form a new path. The new path k + 1 th last last edges and small dots formed in the queue. The first path k times the team is the first k short path. Intuitively feel is right, then prove drawing on paper might come out of it QAQ.

Code:

#include <bits/stdc++.h>
#define LL long long
#define pli pair<LL, int>
#define pii pair<int, int>
using namespace std;
const int maxn = 100010;
vector<pli> G[maxn];
void add(int x, int y, long long z) {
    G[x].push_back(make_pair(z, y));
}
struct edge {
    int u, v;
	LL w;
    bool operator < (const edge& rhs) const {
        return w < rhs.w;
    }
};
edge a[maxn];
LL ans[maxn];
int b[maxn];
struct node {
	int last, now, rank;
	LL dis;
	bool operator < (const node& rhs) const {
		return dis > rhs.dis;
	}
};
priority_queue<node> q;
int main() {
    int T, n, m, t;
    scanf("%d", &T);
    while(T--) {
        while(q.size()) q.pop();
        scanf("%d%d%d", &n, &m, &t);
        for (int i = 1; i <= n; i++) G[i].clear();
        for (int i = 1; i <= m; i++) {
            scanf("%d%d%lld", &a[i].u, &a[i].v, &a[i].w);
            add(a[i].u, a[i].v, a[i].w);
        }
        int lim = 0;
        for (int i = 1; i <= t; i++){
            scanf("%d", &b[i]);
   			lim = max(lim, b[i]);
        }
        for (int i = 1; i <= n; i++) {
        	sort(G[i].begin(), G[i].end());
		}
        for (int i = 1; i <= n; i++) {
        	if(G[i].size()) {
        		q.push((node){i, G[i][0].second, 0, G[i][0].first});
			}
		}
		for (int i = 1; i <= lim; i++) {
			node tmp = q.top();
			q.pop();
			ans[i] = tmp.dis;
			if(G[tmp.now].size())
				q.push((node){tmp.now, G[tmp.now][0].second, 0, tmp.dis + G[tmp.now][0].first});
			if(G[tmp.last].size() > tmp.rank + 1) {
				q.push((node){tmp.last, G[tmp.last][tmp.rank + 1].second, tmp.rank + 1, tmp.dis - G[tmp.last][tmp.rank].first + G[tmp.last][tmp.rank + 1].first});
			}
		}
		for (int i = 1; i <= t; i++) {
			printf("%lld\n", ans[b[i]]);
		}
    }
}

  

Guess you like

Origin www.cnblogs.com/pkgunboat/p/11401971.html