题意:在水平坐标上有N个不同高度的房子,有个人他练习跳跃,他从最矮到高跳跃房子,他每次跳跃的水平距离不超过d。他可以水平移动每座房子,但每座房子不能在一个点,房子坐落的点都是正数点。问最矮的房子离最高的房子最大距离。
解:
差分约束系统,由于人只能从矮的房子跳到高的房子,并且水平跳跃距离最大为的,设此时坐标为Xi,下次跳跃点坐标为Xj的坐标,|Xi-Xj|<=d
由于存在绝对值,不等式就变复杂了,建图也复杂。所以,我们规定大的坐标减小的坐标,打开绝对值符号。
得到N-1个不等式,还有个隐藏条件是相邻的房子坐标差值大于1 ,由于求的答案要最大,因此所有的不等式符号为<=,我们把大于号转化为小于号有得到一个不等式组,通过不等式组建图。
最后要求ph-pl<=?,即最低点到最高点的最大距离。如果ph坐标小于pl,因为之前规定了小坐标指向大坐标,那么转换为pl-ph<=?。
要求最矮的房子离最高的房子最大距离。我们以最矮房子为原点跑最短路(spfa),得到最后的结果。如果SPFA中,某点进入队列超过N次,则无解。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <string.h>
#include <map>
#include <set>
using namespace std;
#define MAXN 1005
#define LL long long
#define INF 0x3f7f7f7f
int n,d;
struct point
{
int id,high;
point(int id=0,int high=0):id(id),high(high){}
friend bool operator<(point x,point y)
{
return x.high<y.high;
}
};
struct point po[MAXN];
struct node
{
int en,len,next;
}Edge[MAXN*MAXN];
int p[MAXN],num;
int dis[MAXN],vis[MAXN],cnt[MAXN];
void init()
{
memset(p,-1,sizeof(p));
num=0;
}
void add(int st,int en,int len)
{
Edge[num].en=en;
Edge[num].len=len;
Edge[num].next=p[st];
p[st]=num++;
}
void spfa(int st,int en)
{
int i;
for(i=1;i<=n;i++)
{
dis[i]=INF;
vis[i]=0;
cnt[i]=0;
}
dis[st]=0;
queue<int>q;
q.push(st);
cnt[st]=1;
vis[st]=1;
while(!q.empty())
{
int tx=q.front();
q.pop();
vis[tx]=0;
for(i=p[tx];i!=-1;i=Edge[i].next)
{
int v=Edge[i].en;
int len=Edge[i].len;
if(dis[v]>dis[tx]+len)
{
dis[v]=dis[tx]+len;
if(!vis[v])
{
vis[v]=1;
cnt[v]++;
if(cnt[v]>n){puts("-1");return ;}//无解
q.push(v);
}
}
}
}
if(dis[en]==INF)puts("-1");
else printf("%d\n",dis[en]);
}
int main()
{
int i;
int t,cas;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
init();
scanf("%d%d",&n,&d);
for(i=1;i<=n;i++)
{
scanf("%d",&po[i].high);
po[i].id=i;
}
sort(po+1,po+1+n);//按高度排序
for(i=2;i<=n;i++)
{
if(po[i].id<po[i-1].id)
add(po[i].id,po[i-1].id,d);//建图
else add(po[i-1].id,po[i].id,d);
}
for(i=1;i<n;i++)
{
add(i+1,i,-1);//相邻点建图
}
printf("Case %d: ",cas);
spfa(min(po[1].id,po[n].id),max(po[1].id,po[n].id));/
}
return 0;
}