hdu 3440 差分约束
相邻的房子间至少要有1的距离,高度相邻的房子间最多能距离d,根据这些条件建图后,要注意一点
要看1和n的相对位置,如果1在n的左边,求1到n的最短路,dis【n】就是答案(排除无解);
否则求n到1的最短路,dis【1】就是答案
错了好几次,inf设的不够大。。。。。
View Code
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
struct node {
int h,id;
}p[1010];
const int INF =1000000000;
struct NODE{
int v,w;
int next;
}list[10000000];
int tot;
int head[1010];
int dis[1010];
int vis[1010];
int cnt[1010];
queue<int> Q;
int n,m;
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
void add(int s,int t,int w)
{
list[tot].v=t;
list[tot].w=w;
list[tot].next=head[s];
head[s]=tot++;
}
int spfa(int src)
{
int i,j,u;
while(!Q.empty()) Q.pop();
memset(vis,0,sizeof(vis));
for(i=0;i<=n;i++)
dis[i]=INF;
Q.push(src);
vis[src]=1;
dis[src]=0;
memset(cnt,0,sizeof(cnt));cnt[src]=1;
while(!Q.empty())
{
u=Q.front();
Q.pop();
vis[u]=0;
for(j=head[u];j!=-1;j=list[j].next)
{
int e=list[j].v;
if(dis[e]>list[j].w+dis[u])
{
dis[e]=list[j].w+dis[u];
if(!vis[e])
{
Q.push(e);
vis[e]=1;
if(++cnt[e]>=n)
return -1;
}
}
}
}
return 0;
}
int cmp(node a,node b)
{
return a.h<b.h;
}
int tmp[1010];
int main()
{
int t,cases=1,i,j,k;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&p[i].h);
p[i].id=i;
}
sort(p+1,p+n+1,cmp);
for(i=1;i<n;i++)
{
if(p[i].id<p[i+1].id) add(i,i+1,m);
else add(i+1,i,m);
}
for(i=1;i<=n;i++)
{
tmp[p[i].id]=i;
}
for(j=1;j<n;j++)
{
add(tmp[j+1],tmp[j],-1);
}
int ans;
if(p[1].id<p[n].id)
{
if(spfa(1)==-1) ans=-1;
else ans=dis[n];
}
else
{
if(spfa(n)==-1) ans=-1;
else ans=dis[1];
}
printf("Case %d: %d\n",cases++,ans);
}
return 0;
}