HDU3440 House Man

2018-04-10 15:42:09 浏览数 (1)

题意:有n栋房子,给出每栋房子的高度和开始时的相对位置,可以移动一些房子,但不能改变这些房子的相对位置,现在从最矮的房子开始,每次跳至比它高的第一栋房子, 而且每次跳跃的水平距离最大是D,房子不能在同一位置,只能在整点位置。问最矮的房子和最高的房子之间的最大距离可以是多少?如果不能从最矮的房子到达最高的房子则输出-1.

分析:令d[i]表示第i栋房子与第一栋房子之间的最大距离,那么我们要求的就是的的d[n],求最短路即可,首先每栋房子之间的相对位置已经确定且不能在同一位置,那么d[i 1] > d[i],每次要跳至比它高的房子上,那么我们需要对房子按高度排序。因为开始时已经规定标号小的点在标号大的点的左边,这样,我们如果从标号大的点到标号小的点,建一条这样的边就会有问题,只能按小到大建边,而且如果两个排序后相邻房子之间的标号大于D的话则不可能到最高的房子,因为房子不可能在同一位置,他们之间的距离至少是D。约束条件只有这两者,建边时需要处理一下方向。最后如果最高的房子标号比矮的房子小的话,则以最高的房子为源点进行spfa,如果存在负环则输出-1.

杭电炸了。。。放个std

代码语言:javascript复制
#include <bits/stdc  .h>  
using namespace std;  
  
const int N = 1010, M = 10000;  
const int INF = 0x3f3f3f3f;  
  
struct house{  
    int he, id;  
    bool operator < (const house& x)const { return he < x.he; }  
}h[N];  
struct edge{  
    int v, d, next;  
    edge(int v, int d, int n):v(v), d(d), next(n){}  
    edge(){}  
}ed[M];  
int head[N], d[N], vis[N], cnt[N];  
int n, s, e, k;  
queue<int> q;  
void init() {  
    k = 0;  
    memset(head, -1, sizeof(int) * n);  
    memset(d, INF, sizeof(int) * n);  
    memset(vis, 0, sizeof(int) * n);  
    memset(cnt, 0, sizeof(int) * n);  
    for (int i = 0;  i < n; i  ) h[i].id = i;  
    while (!q.empty()) q.pop();  
}  
void add(int u, int v, int d) {  
    ed[k] = edge(v, d, head[u]);  
    head[u] = k  ;  
}  
int spfa() {  
    d[s] = 0; cnt[s]  ;  
    q.push(s);  
    while (!q.empty()) {  
        int x = q.front(); q.pop();  
        vis[x] = 0;  
        for (int i = head[x]; i != -1; i = ed[i].next) {  
            int t = ed[i].v;  
            if (d[t] > d[x]   ed[i].d) {  
                d[t] = d[x]   ed[i].d;  
                if (!vis[t]) {  
                    vis[t] = 1; q.push(t);  
                    if (  cnt[t] > n) return -1;  
                }  
            }  
        }  
    }  
    return d[e];  
}  
int main() {  
    int t, ca = 0;  
    scanf("%d", &t);  
    while (t--) {  
        int d;  
        scanf("%d %d", &n, &d);  
        init();  
        for (int i = 0; i < n; i  ) scanf("%d", &h[i].he);  
        sort(h, h n);  
        int flag = 1;  
        for (int i = 0; i < n-1 && flag; i  ) {  
            add(i 1, i, -1);  
            int u = min(h[i].id, h[i 1].id), v = max(h[i].id, h[i 1].id);  
            if (v - u > d) flag = 0;  
            add(u, v, d);  
        }  
        s = min(h[0].id, h[n-1].id), e = max(h[0].id, h[n-1].id);  
        printf("Case %d: %dn",   ca, flag ? spfa() : -1);  
    }  
    return 0;  
}  

0 人点赞