网站如何做入支付接口/制作网站的步骤
链接:点击打开链接
题意:在x轴上有n个房子,现在要求从高度最小的房子递增跳完所有的房子,每次水平跳跃距离小于m,可以移动每个房子的横坐标,但不能改变原始的位置关系,问最低的房子和最高的房子横坐标差的绝对值最大是多少
代码:
#include <stack>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int n,k,dis[1005],cnt[1005],head[1005];
bool vis[1005];
struct edge{int to,w,next;
}G[1005*1005/2];
void addedge(int u,int v,int w){G[k].to=v,G[k].w=w,G[k].next=head[u],head[u]=k++;
}
int spfa(int st,int en){int i,t;stack<int>que;memset(cnt,0,sizeof(cnt));memset(vis,0,sizeof(vis));memset(dis,INF,sizeof(dis));que.push(st);dis[st]=0;while(!que.empty()){t=que.top();que.pop();vis[t]=0;for(i=head[t];i!=-1;i=G[i].next){if(dis[t]+G[i].w<dis[G[i].to]){dis[G[i].to]=dis[t]+G[i].w;if(!vis[G[i].to]){vis[G[i].to]=1;que.push(G[i].to);if(++cnt[G[i].to]>n)return -1;}}}}if(dis[en]==INF)return -1;return dis[en];
}
int a[1005],b[1005],pre[1000005],sign[1000005]; //最短路去查分约束最大值
int main(){ //dis[i+1]>=dis[i]+1,所以i+1->i连条-1的边int i,j,m,t,ans,cas; //但要注意先后顺序,因此需要记住排序前后的位置scanf("%d",&t);for(cas=1;cas<=t;cas++){scanf("%d%d",&n,&m);k=0;memset(pre,0,sizeof(pre));memset(sign,0,sizeof(sign));memset(head,-1,sizeof(head));for(i=1;i<=n;i++){scanf("%d",&a[i]);pre[a[i]]=i;b[i]=a[i];}sort(a+1,a+n+1);for(i=1;i<=n;i++)sign[a[i]]=i;for(i=2;i<=n;i++){ //判断当前点的位置是在前还是在后if(pre[a[i]]>pre[a[i-1]])addedge(i-1,i,m);elseaddedge(i,i-1,m);}for(i=2;i<=n;i++){if(pre[b[i]]>pre[b[i-1]])addedge(sign[b[i]],sign[b[i-1]],-1);elseaddedge(sign[b[i-1]],sign[b[i]],-1);}if(pre[a[1]]<pre[a[n]]) //看起点终点的位置ans=spfa(1,n);elseans=spfa(n,1);printf("Case %d: %d\n",cas,ans);}return 0;
}