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

BT在丛林中探险,目标是收集树上的浆果进行研究。面对有限的能量与复杂的路径选择,通过二分查找与SPFA算法确定最优路径,确保能够往返于营地与目的地之间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值