HDU3440 House Man 【差分约束系统】

House Man

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2056    Accepted Submission(s): 811

Problem Description

In Fuzhou, there is a crazy super man. He can’t fly, but he could jump from housetop to housetop. Today he plans to use N houses to hone his house hopping skills. He will start at the shortest house and make N-1 jumps, with each jump
taking him to a taller house than the one he is jumping from. When finished, he will have been on every house exactly once, traversing them in increasing order of height, and ending up on the tallest house.

The man can travel for at most a certain horizontal distance D in a single jump. To make this as much fun as possible, the crazy man want to maximize the distance between the positions of the shortest house and the tallest house.

The crazy super man have an ability—move houses. So he is going to move the houses subject to the following constraints:

1. All houses are to be moved along a one-dimensional path.

2. Houses must be moved at integer locations along the path, with no two houses at the same location.

3. Houses must be arranged so their moved ordering from left to right is the same as their ordering in the input. They must NOT be sorted by height, or reordered in any way. They must be kept in their stated order.

4. The super man can only jump so far, so every house must be moved close enough to the next taller house. Specifically, they must be no further than D apart on the ground (the difference in their heights doesn‘t matter).

Given N houses, in a specified order, each with a distinct integer height, help the super man figure out the maximum possible distance they can put between the shortest house and the tallest house, and be able to use the houses for training.

Input

In the first line there is an integer T, indicates the number of test cases.(T<=500)

Each test case begins with a line containing two integers N (1 ≤ N ≤ 1000) and D (1 ≤ D ≤1000000). The next line contains N integer, giving the heights of the N houses, in the order that they should be moved. Within a test case, all heights will be unique.

Output

For each test case , output “Case %d: “first where d is the case number counted from one, then output a single integer representing the maximum distance between the shortest and tallest house, subject to the constraints above, or
-1 if it is impossible to lay out the houses. Do not print any blank lines between answers.

Sample Input

3
4 4
20 30 10 40
5 6
20 34 54 10 15
4 2
10 20 16 13 

Sample Output

Case 1: 3
Case 2: 3
Case 3: -1

题意:有N个在一条直线上的房子, 每个房子有着不同的高度, 一个超人可以将这些房子左右移动但不能改变房子之间的相对位置.现在超人要从最矮的房子跳到刚好比他高的房子上面, 且每次跳的房子都要比当前房子要高.那么最后超人肯定会跳到最高的房子上面,
现在给出超人能够跳的最远距离, 问: 如何摆放这些房子, 使得超人能够经过所有的房子跳到最高的房子, 又要使最矮的房子和最高的房子之间的距离最远??(摘自讨论区)

题解:这题关键在建图,建图时让横坐标大的点指向横坐标小的点。

队列:546ms

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#define inf 0x7fffffff
#define maxn 1002
using namespace std;

int head[maxn], dist[maxn], id, out[maxn];
struct Node2{
    int v, num;
} V[maxn];
struct Node{
    int to, d, next;
} E[maxn * maxn];
bool vis[maxn];

bool cmp(Node2 a, Node2 b){
    return a.v < b.v;
}

void addEdge(int u, int v, int d)
{
    E[id].to = v; E[id].d = d;
    E[id].next = head[u]; head[u] = id++;
}

int SPFA(int s, int t, int n)
{
    int i, u, v, tmp;
    for(i = 0; i <= n; ++i){
        dist[i] = inf; vis[i] = 0;
        out[i] = 0;
    }
    u = s; dist[u] = 0; vis[u] = 1;
    queue<int> Q; Q.push(u);
    while(!Q.empty()){
        u = Q.front(); Q.pop(); vis[u] = 0;
        if(++out[u] > n) return -1;
        for(i = head[u]; i != -1; i = E[i].next){
            tmp = dist[u] + E[i].d; v = E[i].to;
            if(tmp < dist[v]){
                dist[v] = tmp;
                if(!vis[v]){
                    vis[v] = 1; Q.push(v);
                }
            }
        }
    }
    return dist[t];
}

int main()
{
    int t, n, m, i, cas = 1, u, v;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &n, &m);
        memset(head, -1, sizeof(head));
        for(i = 1, id = 0; i <= n; ++i){
            scanf("%d", &V[i].v);
            V[i].num = i;
            if(i != n) addEdge(i + 1, i, -1);
        }
        sort(V + 1, V + n + 1, cmp);
        for(i = 1; i < n; ++i){
            u = V[i].num; v = V[i+1].num;
            if(u > v) swap(u, v);
            addEdge(u, v, m);
        }
        printf("Case %d: ", cas++);
        u = V[1].num; v = V[n].num;
        if(u > v) swap(u, v);
        printf("%d\n", SPFA(u, v, n));
    }
    return 0;
}

栈:93ms

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define inf 0x7fffffff
#define maxn 1002
using namespace std;

int head[maxn], dist[maxn];
int sta[maxn], id, out[maxn];
struct Node2{
    int v, num;
} V[maxn];
struct Node{
    int to, d, next;
} E[maxn * maxn];
bool vis[maxn];

bool cmp(Node2 a, Node2 b){
    return a.v < b.v;
}

void addEdge(int u, int v, int d)
{
    E[id].to = v; E[id].d = d;
    E[id].next = head[u]; head[u] = id++;
}

int SPFA(int s, int t, int n)
{
    int i, u, v, tmp, id2;
    for(i = 0; i <= n; ++i){
        dist[i] = inf; vis[i] = 0;
        out[i] = 0;
    }
    u = s; dist[u] = 0; vis[u] = 1;
    id2 = 0; sta[id2++] = s;
    while(id2){
        u = sta[--id2]; vis[u] = 0;
        if(++out[u] > n) return -1;
        for(i = head[u]; i != -1; i = E[i].next){
            tmp = dist[u] + E[i].d; v = E[i].to;
            if(tmp < dist[v]){
                dist[v] = tmp;
                if(!vis[v]){
                    vis[v] = 1; sta[id2++] = v;
                }
            }
        }
    }
    return dist[t];
}

int main()
{
    int t, n, m, i, cas = 1, u, v;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &n, &m);
        memset(head, -1, sizeof(head));
        for(i = 1, id = 0; i <= n; ++i){
            scanf("%d", &V[i].v);
            V[i].num = i;
            if(i != n) addEdge(i + 1, i, -1);
        }
        sort(V + 1, V + n + 1, cmp);
        for(i = 1; i < n; ++i){
            u = V[i].num; v = V[i+1].num;
            if(u > v) swap(u, v);
            addEdge(u, v, m);
        }
        printf("Case %d: ", cas++);
        u = V[1].num; v = V[n].num;
        if(u > v) swap(u, v);
        printf("%d\n", SPFA(u, v, n));
    }
    return 0;
}

HDU3440 House Man 【差分约束系统】

时间: 2024-10-20 13:30:14

HDU3440 House Man 【差分约束系统】的相关文章

差分约束系统

差分约束系统是指一系列不等式: $$ X_j - X_i \le C_{ij}(1\le i, j \le n) $$ 当然 i,j 不必取遍 1-n,而且在扩展的状况下,对于每个(i,j),可以由多个 $C_{ij}$,但是我们很容易把它们化成一个不等式. 在求解不等式组之前,我们可以分析一下这个不等式组的性质. 1. 这个不等式组是可以无解的,比如: $$X_1 - X_2 \le -1 \\ X_2 - X_3 \le -1 \\ X_3 - X_1 \le -1$$ 否则三个不等式相加得

UVa 515 - King (差分约束系统 + SPFA求带负权最短路)

下面是差分约束系统的详细介绍,以及解决方法~ 摘抄自 xuezhongfenfei(他好像也是转的....) 差分约束系统 X1 - X2 <= 0 X1 - X5 <= -1 X2 - X5 <= 1 X3 - X1 <= 5 X4 - X1 <= 4 X4 - X3 <= -1 X5 - X3 <= -3 X5 - X4 <= -3 不等式组(1) 全都是两个未知数的差小于等于某个常数(大于等于也可以,因为左右乘以-1就可以化成小于等于).这样的不等式组

差分约束系统 初见

今天初次学习差分约束系统,很神奇的东西 定义: 如果一个系统由n个变量和m个约束条件组成,其中每个约束条件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),则称其为差分约束系统(system of difference constraints).亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法. 求解差分约束系统,可以转化成图论的单源最短路径(或最长路径)问题. 其实在一些问题中需求最小值或最大值,同时需要满足一系列的不等式关系,这样就可以用到差分约束系统了,对于求最小值的问

ZOJ 3668 Launching the Spacecraft (差分约束系统,最短路)

题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3668 题意: 给一个初始值为0的长度为n的区间,给m个约束l,r,a,b,表示从l到r的区间和>=a且<=b,且每个数的范围为-10000~10000,问这个区间的每个数是多少,要求数尽可能大,且序列字典序最大. 方法: 差分约束系统,以前缀和表示一个节点a[i] 建图:根据下面约束条件建图 a[i]-a[i-1]<=10000 a[i-1]-a[i]&l

POJ 2983 Is the Information Reliable?(差分约束系统)

题目地址:POJ 2983 这题刚上来完全不知道跟差分约束系统有什么关系.....后来发现只要判个负环就可以.. 因为假如有冲突的话会形成一个负环.之所以建图加上一个正值一个负值,是因为这样的话,像1 2 4和1 2 3这样的数据就会形成一个负环.这个方法还是很巧妙的...然后对于V的那些不清楚的位置,就会跟P的那些等式联立形成一个不等式,然后在用最短路判环的过程中就用松弛来解决. 代码如下: #include <iostream> #include <cstdio> #inclu

【POJ 1201】 Intervals(差分约束系统)

[POJ 1201] Intervals(差分约束系统) 11 1716的升级版 把原本固定的边权改为不固定. Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23817   Accepted: 9023 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a p

差分约束系统--详讲

------------差分约束题目请戳:差分约束题集暨报告 总的开说差分约束问题就是给出一系列不等式然后求问某一式子的最大值或者最小值. 差分约束问题具体解释: 比方有这样一组不等式: X1 - X2 <= 0 X1 - X5 <= -1 X2 - X5 <= 1 X3 - X1 <= 5                   不等式组(1) X4 - X1 <= 4 X4 - X3 <= -1 X5 - X3 <= -3 X5 - X4 <= -3 全都是

浅谈差分约束系统——图论不等式的变形

浅谈差分约束系统——图论不等式的变形 ----yangyaojia 版权声明:本篇随笔版权归作者YJSheep(www.cnblogs.com/yangyaojia)所有,转载请保留原地址! 一.定义 如若一个系统由n个变量和m个不等式组成,并且这m个不等式对应的系数矩阵中每一行有且仅有一个1和-1,其它的都为0,这样的系统称为差分约束( difference constraints )系统. 二.分析 简单来说就是给你n个变量,给m个形如x[i]-x[j]≥k①或x[i]-x[j]≤k②.求两

UVA11478 Halum [差分约束系统]

https://vjudge.net/problem/UVA-11478 给定一个有向图,每条边都有一个权值.每次你可以选择一个结点v和一个整数d,把所有以v为终点的边的权值减小d,把所有以v为起点的边的权值增加d,最后让所有边的权值的最小值大于零且尽量大. 该死书上翻译错了 >0不是非负 WA好几次因为这个 考虑每条边的约束,di表示i的halum量 w-dv+du>0 dv-du<w 但求解这个差分约束系统只是让这组不等式成立,最长路和最短路控制的都是单个d的最值而不是最小值最大 那