前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDU3440 House Man

HDU3440 House Man

作者头像
attack
发布2018-04-10 15:42:09
4880
发布2018-04-10 15:42:09
举报

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

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

杭电炸了。。。放个std

#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: %d\n", ++ca, flag ? spfa() : -1);  
    }  
    return 0;  
}  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档