HDU House Man
思路
很显然,第\(k\)高的必须向第\(k+1\)高的连一条\(D\)的边权
因为所有房屋的顺序不能改变那就是\(x_{i+1} - x_{i} >= 1\)
即\(x_{i } - x_{i+1} <= -1\) 也就是\(i+1\)向\(i\)连一条\(-1\)的边
code
#include <bits/stdc++.h>
#define ll long long
#define N 1010
#define M 1010
using namespace std;
struct node {
int next, to, dis;
void clear() {
next = to = dis = 0;
}
}edge[N << 2];
struct PPP {
int x, id, bian;
}point[M];
int add_edge, head[N << 2];
int n, m, st, ed, vis[M], pts[M], dis[M];
int read() {
int s = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
}
void init() {
for (int i = 1; i <= add_edge; i++) edge[i].clear();
add_edge = 0; memset(head, 0, sizeof head);
}
bool cmp(PPP a, PPP b) {
return a.x < b.x;
}
void add(int from, int to, int dis) {
edge[++add_edge].next = head[from];
edge[add_edge].to = to;
edge[add_edge].dis = dis;
head[from] = add_edge;
}
int spfa(int st) {
memset(vis, 0, sizeof vis);
memset(pts, 0, sizeof pts);
memset(dis, 0x3f, sizeof dis);
queue<int> q; q.push(st);
dis[st] = 0, vis[st] = 1;
while (!q.empty()) {
int fr = q.front();
q.pop(), vis[fr] = 0;
for (int i = head[fr]; i; i = edge[i].next) {
int to = edge[i].to;
if (dis[to] > dis[fr] + edge[i].dis) {
dis[to] = dis[fr] + edge[i].dis;
if (!vis[to]) {
pts[to]++;
if (pts[to] == n) return -1;
vis[to] = 1, q.push(to);
}
}
}
}
return dis[ed];
}
int main() {
int T = read(), ss = T;
while (T--) {
init();
n = read(), m = read();
for (int i = 1; i <= n; i++) {
point[i].id = i, point[i].x = read();
if (i != n) add(i + 1, i, -1);
}
sort(point + 1, point + n + 1, cmp);
for (int i = 1; i < n; i++) {
int x = point[i].id, y = point[i + 1].id;
if (x > y) swap(x, y);
add(x, y, m);
}
st = point[1].id, ed = point[n].id;
if (st > ed) swap(st, ed);
int sy = spfa(st);
printf("Case %d: %d\n", ss - T, sy);
}
}