青蛙表演 [差分约束]

青蛙表演 [差分约束]

问题描述

何老板训练了一只青蛙,该蛙擅长跳跃。它经常从一片荷叶跳到另一片荷叶。今天,何老板打算用N根木桩来向世人展示该蛙的跳跃技能。
这n根木桩排成一行,蛙首先从最矮的木桩顶部起跳,总共进行N-1次跳跃。每次它只能跳到比当前木桩更高的一个木桩顶部。当表演结束时,每个木桩它都恰好到过一次,最终停在最高的木桩顶部。
这只青蛙向上跳跃能力很强,但水平方向跳跃能力就有限了,每次跳跃,它在水平方向飞行的距离不超过D米。舞台上给出的这N根木桩的排列顺序不可改变,但木桩间的间距可以任意调整,但间距必须是整数而且至少为1,且两根木桩不能位于同一点上。何老板想知道,在成功完成表演的前提下,最矮跟最高的那根木桩的间距最大可能是多少?如果无论如何都不能完成表演,输出-1

输入格式

第一行,两个空格间隔的整数N和D
第二行,N个空格间隔的整数,依次给出了每根木桩的高度,不会有相同高度的木桩,木桩的高度在int范围以内。

输出格式

一个整数,表示最矮和最高木桩可能的最大间距
若不可能完成表演,输出-1

显然差分约束啦。

这题的约束条件很明显:①相邻两根木桩之间的距离大于等于1,②相邻高度木桩之间的距离小于等于d。

由于连成的图肯定连通,所以不用加超级源点。

但是,这道题有个坑点,导致我只得了50:我们知道,对于相邻高度的木桩i和j,有Xi-Xj<=d,然而,这是对于i>j的情况而言的,就是说,这样的约束条件必须是i在j后面的。如果i在j前面,就有Xj-Xi<=d。跑最短路的时候也要注意,最高和最矮的柱子的位置关系。详细见代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#define N 1000010
using namespace std;
int End[N<<1],Last[N<<1],Next[N<<1],cnt,dis[N],ti[N],w[N];
int n,d;bool used[N];
struct node{
    int h,id;
    bool operator<(const node &a)
        const{return h>a.h;}
}in[N];
void Ins(int x,int y,int v){
    End[++cnt]=y,w[cnt]=v;
    Next[cnt]=Last[x],Last[x]=cnt;
}
bool SPFA(int s){
    queue<int>q;
    for(int i=0;i<=n+1;i++)dis[i]=1e9,used[i]=0;
    dis[s]=0,q.push(s);
    while(!q.empty()){
        int u=q.front();q.pop();used[u]=false;
        for(int i=Last[u];i;i=Next[i]){
            int v=End[i];
            if(dis[v]>dis[u]+w[i]){
                dis[v]=dis[u]+w[i];
                if(!used[v]){
                    ti[v]++;
                    if(ti[v]>n)return false;
                    used[v]=true;q.push(v);
                }
            }
        }
    }
    return true;
}
int main(){
    int Ans;scanf("%d%d",&n,&d);
    for(int i=1;i<=n;i++){
        scanf("%d",&in[i].h);
        in[i].id=i;
        if(i>1)Ins(i,i-1,-1);
    }
    sort(in+1,in+n+1);
    //一定要判断相邻高度的柱子的位置关系
    for(int i=2;i<=n;i++){
        if(in[i].id<in[i-1].id)Ins(in[i].id,in[i-1].id,d);
        else Ins(in[i-1].id,in[i].id,d);
    }
    //判断最矮的柱子和最高的柱子的位置关系
    if(in[1].id<in[n].id)
        if(SPFA(in[1].id))Ans=dis[in[n].id];else Ans=-1;
    else if(SPFA(in[n].id))Ans=dis[in[1].id];else Ans=-1;
    printf("%d",Ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ArliaStark/article/details/80372146