hdu 3440(差分约束好题)

时间:2024-10-16 18:33:56

House Man

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2410    Accepted Submission(s): 978

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
题意:一个人要从高度最低的房子开始跳到高度最高的房子,每次只能跳到与它本身的高度相邻的房子,每次能够跳的最大距离是D,问最低的房子和最高的房子的最大距离.
题解:这题我首先就想排序,然后再按编号对两个房子连一条边..结果死活做不出来,然后发现漏掉了一点,我们是要考虑房子的编号的。。有向边我们规定是从编号小的连向编号大的,所以我们无论是建图还是找最短路,都要从编号小的找到编号大的。这一点比较难想到.然后就很简单了,如果有负环或者没有松弛就不可达。其余情况输出最小值。
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <queue>
using namespace std;
const int N = ;
const int INF = <<;
struct Node{
int h,id;
}node[N];
struct Edge{
int v,w,next;
}edge[N*(N-)];
int head[N],n;
void addEdge(int u,int v,int w,int &k){
edge[k].v = v,edge[k].w=w,edge[k].next=head[u],head[u]=k++;
}
int cmp(Node a,Node b){
return a.h<b.h;
}
bool vis[N];
int low[N];
int time[N];
int spfa(int s,int e){
queue<int>q;
for(int i=;i<=n;i++){
vis[i] = false;
time[i] = ;
low[i] = INF;
}
time[s]++;
low[s] = ;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int k = head[u];k!=-;k=edge[k].next){
int v = edge[k].v,w=edge[k].w;
if(low[v]>low[u]+w){
low[v] = low[u]+w;
if(!vis[v]){
vis[v] = true;
q.push(v);
if(time[v]++>n) return -;
}
}
}
}
if(low[e]>=INF) return -;
return low[e];
}
int main()
{
int tcase;
scanf("%d",&tcase);
int t=;
while(tcase--){ memset(head,-,sizeof(head));
int D;
int tot = ;
scanf("%d%d",&n,&D);
for(int i=;i<=n;i++){
scanf("%d",&node[i].h);
node[i].id = i;
}
sort(node+,node++n,cmp);
for(int i=;i<n;i++){
addEdge(i+,i,-,tot);
}
for(int i=;i<n;i++){
int a = max(node[i].id,node[i+].id);
int b = min(node[i].id,node[i+].id);
addEdge(b,a,D,tot);
}
int s = min(node[n].id,node[].id);
int e = max(node[n].id,node[].id);
int c = spfa (s,e);
printf ("Case %d: %d\n",t++,c);
}
}