hdu3440 House Man

有n个房子,严格按从矮到高依次跳,跳的两个房子之间的距离要<=d,

差分约束。求最长路,按y-x<=d 建边。

需要注意的是,按高度排序后建边,需要考虑1和n的顺序问题。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define eps 1e-6
#define ll long long
const int maxn=1010;
const int maxm=1000000;
using namespace std;

struct edge
{
    int h,id;
}p[maxn];

struct node
{
    int v,w,next;
}e[maxm];

int h,head[maxn],d[maxn],inq[maxn],outq[maxn],n,pre[maxn];

bool cmp(edge a,edge b)
{
    return a.h<b.h;
}

void init()
{
    memset(head,-1,sizeof head);
    h=0;
}

void addedge(int a,int b,int c)
{
    e[h].v=b;
    e[h].w=c;
    e[h].next=head[a];
    head[a]=h++;
}

int spfa(int s)
{
    int i,v,w,x;
    for(i=0;i<=n;i++)
        d[i]=1000000000;
    memset(inq,0,sizeof inq);
    memset(outq,0,sizeof outq);
    queue<int> q;
    q.push(s);
    inq[s]=1;
    d[s]=0;
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        inq[x]=0;
        outq[x]++;
        if(outq[x]>n) return -1;
        for(i=head[x];i!=-1;i=e[i].next)
        {
            v=e[i].v;
            w=e[i].w;
            if(d[v]>w+d[x])
            {
                d[v]=w+d[x];
                if(!inq[v])
                {
                    inq[v]=1;
                    q.push(v);
                }
            }
        }
    }
    return 1;
}

int main()
{
    int icy,i,D,T=1,s,t;
    scanf("%d",&icy);
    while(icy--)
    {
        init();
        scanf("%d%d",&n,&D);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&p[i].h);
            p[i].id=i;
        }
        sort(p+1,p+n+1,cmp);
        for(i=2;i<=n;i++)
        {
            pre[p[i].id]=i;
            if(p[i-1].id<p[i].id) addedge(i-1,i,D);
            else addedge(i,i-1,D);
        }
        pre[p[1].id]=1;
        for(i=2;i<=n;i++)//原来相邻的房子 要用现在的编号来建边
            addedge(pre[i],pre[i-1],-1);

        if(p[1].id<p[n].id) s=1,t=n;
        else s=n,t=1;
        printf("Case %d: ",T++);
        if(spfa(s)==-1) printf("-1\n");
        else printf("%d\n",d[t]);
    }
    return 0;
}

hdu3440 House Man

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

hdu3440 House Man的相关文章

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 hou

HDU3440 House Man【SPFA】【差分约束】

House Man Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2160    Accepted Submission(s): 849 Problem Description In Fuzhou, there is a crazy super man. He can't fly, but he could jump from hou

hdu 3440 House Man

https://vjudge.net/problem/HDU-3440 题意: 一个超人,他可以一个从一栋楼跳到另一栋楼.有一天,他为了加强技能,准备跳一系列的楼,他每次都从低的楼,跳到高的楼.他从最低的楼开始跳,但是他跳的水平距离是有限制的. 但是因为他是超人,所以他可以任意移动楼,而且他想他开始跳的楼与最后跳到的楼的距离最大. 他移动楼的时候有某些限制: 1.移动之后的楼的排列顺序必须与输入的顺序相同. 2.必须满足水平跳跃的距离的限制. 求这个最大距离,如果跳不到的话,输出-1. 思路:

浅谈差分约束问题

差分约束 差分约束是解决这样一类问题 给出\(n\)个形如\(x[j]-x[i]<=k\)的式子,求\(x[n]-x[1]\)的最大/最小值 思路 其实这个问题是挺套路的 我们把给出的式子变一下 \(x[j]-x[i]<=k\) \(x[j]<=x[i]+k\) 我们不难联想到图论中最短路的性质 假设\(d[x]\)表示\(1\)到\(x\)的最短路 那么对于任意一条边\((u,v)\) 有\(d[v]<=d[u]+k\)(k表示边权) 可能有些抽象,举个例子 经过计算不难得到三个