POJ_1716

    由于有了前面几个题目的基础,解答这个题目的过程还算顺利。我们设S[i]为区间[0,i)内选取的数字的数量,那么有①S[b+1]-S[a]>=2,②S[i+1]-S[i]>=0,③S[i]-S[i+1]>=-1。这样以max(b)+1为起点,以min(a)为终点求一个最短路就可以了,最后的结果为d[max(b)+1]-d[min(a)]

#include<stdio.h>
#include
<string.h>
int first[10010],next[30010],v[30010],w[30010];
int inq[10010],q[10010],d[10010];
int main()
{
int i,j,k,a,b,e,u,n,max,min,front,rear,N;
while(scanf("%d",&n)==1)
{
memset(first,
-1,sizeof(first));
max
=0;
min
=10000;
for(e=0;e<n;e++)
{
scanf(
"%d%d",&a,&b);
if(a<min)
min
=a;
if(b>max)
max
=b;
v[e]
=a;
w[e]
=-2;
next[e]
=first[b+1];
first[b
+1]=e;
}
for(i=min;i<max+1;i++)
{
v[e]
=i+1;
w[e]
=1;
next[e]
=first[i];
first[i]
=e;
e
++;
v[e]
=i;
w[e]
=0;
next[e]
=first[i+1];
first[i
+1]=e;
e
++;
}
for(i=min;i<=max+1;i++)
{
d[i]
=100000;
inq[i]
=0;
}
N
=max-min+1;
d[max
+1]=0;
front
=rear=0;
q[rear
++]=max+1;
while(front!=rear)
{
u
=q[front++];
if(front>N)
front
=0;
inq[u]
=0;
for(e=first[u];e!=-1;e=next[e])
if(d[u]+w[e]<d[v[e]])
{
d[v[e]]
=d[u]+w[e];
if(!inq[v[e]])
{
q[rear
++]=v[e];
if(rear>N)
rear
=0;
inq[v[e]]
=1;
}
}
}
printf(
"%d\n",d[max+1]-d[min]);
}
return 0;
}

  

posted on 2011-08-15 16:27  Staginner  阅读(339)  评论(0编辑  收藏  举报