zoukankan      html  css  js  c++  java
  • 解题报告 Trick

    Trick

    【题目描述】

    暴躁的稻草人,最终以自爆来给我们的队伍致命一击,全队血量见底,稻草人也一分为二。还好我们有雨柔妹子,瞬间精力回满。不过事后姜小弟和龙腹黑就开始了报复。

    他们读取存档,将若干暴躁的稻草人活捉。然后将它们放到一个迷宫的入口。迷宫是有向图。此刻暴躁的稻草人们在1号位置,而迷宫出口在n号位置。因为稻草人会自爆,所以他每经过一条路数量就会加倍。每条路上敌人,会消耗稻草人c[i](c[i]为负值);当然有些时候路上也会遇到止血草之类的东西,这时候就可以补充一些稻草人(c[i]为正值)。如果小稻草人死光了,那么稻草人也就可以看做是挂了。希望你帮助稻姜龙二人算出用最少的初始稻草人使其能够走出迷宫

    【输入格式】

    第一行两个数N<=50000),M<=100000)表示点位数与边数。

    以下M行,每行三个数abc表示ab两点间的边权是c|c|<=10000

    【输出格式】

    输出仅一个整数,表示最小初始稻草人数(在 [1,10000] 之间

    【输入样例】

      5 4
      1 2 -3
      1 3 -6
      3 4 1
      4 5 -9

    【输出样例】

      4

     

    首先,他给出答案的范围了,所以可以二分答案。

    二分一开始有几个,然后跑最长路,看看能不能到头。

    并且,如果遇到了环,则稻草人可以无限增加,所以可以直接得到答案,但还要继续二分,因为他让求最小的。

     

    不过,还有第二种思路:可以发现,当用最少的稻草人开始走的时候,到达终点,一定只剩一个。

    所以,倒着搜,就可以了。

     

     

     

    二分答案(魂之挽歌)

    program test2;

    const dd=100000;

    type bian=record

          y,l,next:longint;

         end;

    var a:array[0..100010]of bian;

        dist:array[0..50010]of int64;

        v:array[1..50000]of boolean;

        d:array[0..100000]of longint;

        g:array[0..50000]of longint;

        s:array[0..50001]of longint;

        i,j,m,n,x,y,l,ans:longint;

    function spfa(k:longint):boolean;

    var t,w,i,x:longint;

    begin

        fillchar(dist,sizeof(dist),0);

        fillchar(v,sizeof(v),0);

        fillchar(s,sizeof(s),0);

        t:=0;w:=1;d[w]:=1;v[1]:=true;dist[1]:=k;

        s[1]:=1;

        while t<>w do

        begin

            t:=(t+1)mod dd;x:=d[t];i:=g[x];

            while i<>0 do

            begin

                if dist[a[i].y]<dist[x]*2+a[i].l then

                begin

                    dist[a[i].y]:=dist[x]*2+a[i].l;

                    inc(s[a[i].y]);

                    if s[a[i].y]>n then exit(true);

                    if not v[a[i].y] then

                    begin

                        v[a[i].y]:=true;

                        w:=(w+1)mod dd;

                        d[w]:=a[i].y;

                    end;

                end;

                i:=a[i].next;

            end;

        end;

        if dist[n]>0 then exit(true);

        exit(false);

    end;

    procedure find(l,r:longint);

    var mid:longint;

    begin

        if l>r then exit;

        mid:=(l+r)shr 1;

        if spfa(mid) then

        begin

            ans:=mid;

            find(l,mid-1);

        end

        else find(mid+1,r);

    end;

    begin

    assign(input,'trick.in');reset(input);

    assign(output,'trick.out');rewrite(output);

        readln(n,m);

        for i:=1 to m do

        begin

            readln(x,y,l);

            a[i].y:=y;

            a[i].l:=l;

            a[i].next:=g[x];

            g[x]:=i;

        end;

        find(1,10000);

        writeln(ans);

    close(input);close(output);

    end.

     

     

     

    倒着推(Ray

    program lonely;

      const

        maxn=100010;

      type

        nod=record

          x,y,len,next:longint;

        end;

      var

        map:array[0..100010] of nod;

        first:array[0..50000] of longint;

        que:array[0..100010] of longint;

        dist:array[0..50010] of int64;

        v:array[0..50010] of boolean;

     

        temp,head,tail,tot,x,y,len,t,i,n,m:longint;

     

      begin

        assign(input,'trick.in');

        reset(input);

        assign(output,'trick.out');

        rewrite(output);

        readln(n,m);

        for i:=1 to m do

          begin

            readln(y,x,len);

            len:=-len;

            map[i].x:=x;map[i].y:=y;map[i].len:=len;

            map[i].next:=first[x];first[x]:=i;

          end;

        fillchar(que,sizeof(que),0);

        fillchar(v,sizeof(v),false);

        filldword(dist,sizeof(dist)>>2,maxlongint>>1);

        head:=0;tail:=1;

        que[tail]:=n;

        dist[n]:=1;

        v[n]:=true;

        while head<>tail do

          begin

            inc(head);

            if head>maxn then head:=1;

            x:=que[head];

            t:=first[x];

            while t<>0 do

              begin

                y:=map[t].y;

                temp:=dist[x]+map[t].len;

                if ((temp-1) div 2+1<dist[y])and(dist[x]>0)and(dist[y]>1) then

                  begin

                    dist[y]:=(temp-1) div 2+1;

                    if dist[y]<0 then dist[y]:=1;

                    if not v[y] then

                      begin

                        v[y]:=true;

                        inc(tail);

                        if tail>maxn then tail:=1;

                        que[tail]:=y;

                      end;

                  end;

                t:=map[t].next;

              end;

            v[x]:=false;

          end;

        writeln(dist[1]);

        close(input);

        close(output);

      end.

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    【转载】关于sql的执行计划(推荐详细) 天高地厚
    填充因子 天高地厚
    【转载】基于Windows下的Web性能测试和压力测试 天高地厚
    [转]SQL Server 2008存储结构之GAM、SGAM 天高地厚
    用sp_change_users_login消除Sql Server的孤立用户
    定义类成员
    个人JS脚本验证大全[转]
    网页居中
    转 优先队列 的使用
    java BigInteger
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2216482.html
Copyright © 2011-2022 走看看