【2017.8.6普及模拟】最大(max)

xiaoxiao2021-02-28  131

【2017.8.6普及模拟】最大(max)

题目:

走进丛林的BT开始了他在丛林的探险,一天晚上,BT坐在篝火旁,无聊地看着地图,他在回忆着进入丛林的经过……   他发现,丛林的每棵树上都有些浆果,这些浆果都是他没见过的,所以BT想把这些果子都拿回去做研究,然而BT认为一次那太多会很不爽,所以他想知道,他从营地到准备考察的地方,一每棵树上的浆果最大值的最小值。当然,BT的早餐能量有限,而从一棵树到另一棵树所需能量是已知的,BT要保证来回所需能量小于等于早餐所提供的能量。

输入:

  第一行5个正整数,n(1<=n<=10000),m(1<=m<=25000),s,t,st。分别表示有n棵树,m条路径,从营地s到考察处t,早餐的能量为st。         接下来有n行,每行1个正整数,fi。表示第i棵树上的浆果重量。 再接下来有m行,每行3个正整数,x,y,d (1<=x,y<=n)。表示第x棵树和第y棵树之间可通行,且所需能量为d。

输出:

  一行,路径上浆果重量最大值的最小值。若BT无法从营地和考察地间走一个来回,则输出-1.

比赛的时候打了个递归

理所当然的40分

听DALAO讲解后恍然大悟

我们二分出答案

用答案来标记所有点是否可用

if weight[i]<=mid then bz[i]:=true(可用)

else bz[i]:=false;(不可用)

从起点到终点做一遍SPFA

然后

if dis[终点]<=早餐营养值 then r:=mid-1

else l:=mid+1;

标程:(请勿抄袭,后果很严重)

var n,m,s,t,i,j,k,x:longint; ans,ka,l,r,mid:int64; weight:array[1..10000]of int64; d:array[0..50000]of int64; a:array[0..50000,1..2]of longint; st,en:array[0..10000]of longint; bz,bj:array[1..10000]of boolean; data:array[0..5000000]of longint; dis:array[0..10000]of int64; procedure qsort(l,r:longint); var i,j,mid:longint; begin i:=l; j:=r; mid:=a[(l+r)div 2,1]; repeat while a[i,1]<mid do inc(i); while a[j,1]>mid do dec(j); if i<=j then begin a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0]; inc(i); dec(j); end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j); end; begin assign(input,'max.in'); assign(output,'max.out'); reset(input); rewrite(output); readln(n,m,s,t,ka); for i:=1 to n do readln(weight[i]); for i:=1 to m do begin readln(a[i*2-1,1],a[i*2-1,2],d[i*2-1]); a[i*2,1]:=a[i*2-1,2]; a[i*2,2]:=a[i*2-1,1]; d[i*2]:=d[i*2-1]; end; qsort(1,m*2); st[a[1,1]]:=1; en[a[1,1]]:=1; for i:=2 to m*2 do if a[i,1]=a[i-1,1] then inc(en[a[i,1]]) else begin st[a[i,1]]:=i; en[a[i,1]]:=i; end;//边集存储 l:=1; r:=maxlongint; while l<=r do //二分 begin mid:=(l+r)div 2; if mid=3900 then writeln; fillchar(bz,sizeof(bz),1); for i:=1 to n do if weight[i]>mid then bz[i]:=false;//标记可用点 fillchar(bj,sizeof(bj),1); bj[s]:=false; data[1]:=s; i:=0; j:=1; fillchar(dis,sizeof(dis),$7f); dis[s]:=0; if bz[s] then while i<j do begin inc(i); if st[data[i]]<>0 then for k:=st[data[i]] to en[data[i]] do if(dis[a[k,2]]>dis[data[i]]+d[k])and(bz[a[k,2]])then begin dis[a[k,2]]:=dis[data[i]]+d[k]; if bj[a[k,2]] then begin inc(j); data[j]:=a[k,2]; bj[a[k,2]]:=false; end; end; bj[data[i]]:=true; end;//SPFA if dis[t]<=ka then r:=mid-1 else l:=mid+1; end; writeln(l); close(input); close(output); end.

转载请注明原文地址: https://www.6miu.com/read-51914.html

最新回复(0)