tyvj P1248 - 丛林探险

P1248 - 丛林探险

From Admin    Normal (OI) 总时限:10s    内存限制:128MB

描述 Description

东非大裂谷中有一片神秘的丛林,是全世界探险家的乐园,著名黄皮肤探险家BiBo一直想去试试。正好我国科学家2005年4月将首次对东非大裂谷进行科考,BiBo决定随科考队去神秘丛林探险。在出发之前,他搜集了国内外有关神秘丛林探险的资料,并绘制成一张地图:该地图上有若干安全点(包括入口点和出口点),并将这些安全点编号为1、2、…、n;如果一个安全点和另一个安全点有一条路直接相通,则用一条边标示;该图是一个连通图(任意两点间有至少一条路径),地图上每条路的长度和走这条路需要耗费的体力都做了标示。 BiBo行走速度为1,并知道自己体力为K。他想知道根据自己的体力情况能否成功地穿过丛林。

输入格式 InputFormat

第一行两个整数n(<=5000)  m(<=40000),分别表示地图上安全点的个数和边的数目; 第2行至第m+1 行每行4个整数x  y  c d,x、y表示有直接相联边的两个点的编号,c走这条路需要耗费的体力;d表示边的长度;(其中150<=c,d<=300) 第m+2行两个整数s  t,分别表示安全的入口点和出口点的编号; 第m+3行一个整数k,表示BB的体力值;(K<10^9) 同一行上的多个数据用空格隔开。

输出格式 OutputFormat

一个整数,如果BiBo能安全地从如入口穿过丛林到达出口,输出最短时间,否则输出-1

样例输入 SampleInput [复制数据]

4 5
1 2 2 3
1 3 3 5
1 4 7 10
2 4 4 6
3 4 2 6
1 4
5

样例输出 SampleOutput [复制数据]

11

时间限制 TimeLimitation

各个测试点1s
题解:双关键字SPFA 如果数据正常的话 应该两遍SPFA从1-n一次 从n-1一次 然后根据主次限制条件关系进行relax 但是ty的数据太渣了...直接一遍SPFA 就能A 然后用邻接表存..要不然会MLE【像我这个渣一样】  relax的条件
if (d[k].a+c<=sum)and((d[k].b+s<d[t].b)or((d[k].b+s=d[t].b)and(d[k].a+c<d[t].a))) then
  d[k].a表示到k的体力 c为路径上体力消耗 d[k].b就是最短路 s为路径长度 松弛的必然必要条件之一要<=sum【最大体力】if (d[k].a+c<=sum)
然后 再和主次限制 and((d[k].b+s<d[t].b)or((d[k].b+s=d[t].b)and(d[k].a+c<d[t].a))) 就OK了...
program tyvj1248; type node=record a,b:longint; end; var     b:array[0..80000,1..4] of longint; a:array[0..5000] of longint; q:array[1..10000] of integer; d:array[1..5000] of node; mark:array[1..5000] of boolean; n,m,x,y,l,sum,k,t,head,tail,first,c,z,kk,i,s:longint; procedure push(k:longint); begin inc(head);q[head]:=k; mark[k]:=true; end; function pop:longint; begin pop:=q[tail]; inc(tail); end; begin readln(n,m);z:=0; for i:=1 to m do begin readln(x,y,c,s); inc(z);b[z,1]:=y;b[z,2]:=c;b[z,3]:=s;b[z,4]:=a[x];a[x]:=z; inc(z);b[z,1]:=x;b[z,2]:=c;b[z,3]:=s;b[z,4]:=a[y];a[y]:=z; end; readln(first,l); readln(sum); for i:=1 to n do begin d[i].a:=maxlongint;d[i].b:=maxlongint; end; d[first].a:=0;d[first].b:=0; head:=0;tail:=1; push(first); while head>=tail do begin k:=pop;kk:=a[k]; while kk<>0 do begin t:=b[kk,1];c:=b[kk,2];s:=b[kk,3]; if (d[k].a+c<=sum)and((d[k].b+s<d[t].b)or((d[k].b+s=d[t].b)and(d[k].a+c<d[t].a))) then begin d[t].a:=d[k].a+c; d[t].b:=d[k].b+s; if not mark[t] then push(t); end; kk:=b[kk,4]; end; mark[k]:=false; end; if d[l].a<=sum then writeln(d[l].b) else writeln(-1); end.

posted on 2012-10-31 11:10  馒头~blue  阅读(219)  评论(0编辑  收藏  举报

导航