hdu 5361 In Touch(最短路+并查集)

来源:互联网 发布:中国大学生软件杯 编辑:程序博客网 时间:2024/06/16 12:46

题目链接:hdu 5361 In Touch


最短路,D[i]表示从i节点出发时最短距离,最后答案减掉C[i]即可。然后用并查集优化维护处理过的节点。


#pragma comment(linker, "/STACK:102400000,102400000")#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 2 * 1e5 + 5;const ll inf = 1LL << 60;struct Pi {int pos;ll dis;Pi (int pos = 0, ll dis = 0): pos(pos), dis(dis) {}bool operator < (const Pi& u) const {return dis > u.dis;}};int N, L[maxn], R[maxn], C[maxn], F[maxn];ll D[maxn];int find (int x) {return F[x] = (F[x] == x ? x : find(F[x]));}void init () {scanf("%d", &N);for (int i = 1; i <= N; i++) {F[i] = i;D[i] = inf;}for (int i = 1; i <= N; i++)scanf("%d", &L[i]);for (int i = 1; i <= N; i++)scanf("%d", &R[i]);for (int i = 1; i <= N; i++)scanf("%d", &C[i]);}void solve (int s) {D[s] = C[s];priority_queue<Pi> Q;Q.push(Pi(s, D[s]));while (!Q.empty()) {int u = Q.top().pos;Q.pop();for (int i = -1; i <= 1; i += 2) {int lp = u + L[u] * i;int rp = u + R[u] * i;if (lp > rp)swap(lp, rp);lp = max(lp, 1);lp = min(lp, N + 1);if (lp > rp)continue;while (true) {lp = find(lp);if (lp <= 0 || lp > N || lp > rp)break;if (D[lp] > D[u] + C[lp]) {D[lp] = D[u] + C[lp];Q.push(Pi(lp, D[lp]));}F[find(lp)] = find(lp + 1);lp++;}}}printf("0");for (int i = 2; i <= N; i++)printf(" %I64d", D[i] == inf ? -1 : D[i] - C[i]);printf("\n");}int main () {int cas;scanf("%d", &cas);while (cas--) {init();solve(1);}return 0;}


0 0
原创粉丝点击