hdu 5361 In Touch(最短路+并查集)
2015-08-07 19:22
295 查看
题目链接: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;
}
最短路,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;
}
相关文章推荐
- 杭电acm 2139 Calculate the formula
- Java IO流--IO包中的其他类
- 【bzoj2141】 排队 树状数组+主席树
- Python简单爬虫
- HDU 5355 Cake(数学 DFS)
- POJ-2136 Vertical Histogram-用*号统计字母个数
- C++(12)STL实践与分析之顺序容器
- Python正则表达式速查表
- hdu 2084 - 数塔(解题报告)
- codeforces Gym 100418D BOPC 打表找规律,求逆元
- java容器类---ArrayList
- 简介BFC
- POJ-1833 排列-字典序
- List,Map的遍历
- 考试排名(一)(结构体专题)
- ANDROID内存优化——大汇总(转)
- 【CODEFORCES】 A. Expression
- poj 1185 炮兵阵地 (状态压缩)
- Period(kmp)
- hdu 5360 Hiking(贪心)