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

    3.xth的旅行(trip.pas/c/cpp)

    描述

    毕业了,Xth很高兴,因为他要和他的rabbit去双人旅行了。他们来到了水城威尼斯。众所周知(⊙﹏⊙b汗),这里的水路交通很发达,所以xth和rabbit只好坐船穿梭于各个景点之间。但是要知道,rabbit是会晕船的,看到她难受,xth是会心疼的。

    已知城市中有n个景点,这些景点之间有m条双向水路,在每条水路上航行时rabbit都会有一个“晕船值”。旅行时,xth会带着rabbit尽量选择晕船值小的路线旅行。但是rabbit也是有一定忍耐限度度的,如果晕船值超过了她的忍耐度,xth会果断决定放弃这条路线。

    现在xth想进行若干次询问,给定rabbit的忍耐度,问还有多少对城市(x,y)间会存在可行的旅行路线(如果(x,z)和(z,y)可行,则(x,y)可行,也就是说连通性是可传递的)。

    输入格式

    第1行三个正整数n、m、Q,分别表示景点数量、水路数量和询问次数。

    第2行到第m+1行每行三个正整数x、y、w,表示x号景点和y号景点之间有一条“晕船值”为w的双向水路

    第m+2行至第m+Q+1行,每行一个正整数k,表示询问中给定的rabbi忍耐度为k。

    输出格式

    共Q行,对于每次询问做出回答。

    样例输入 Sample Input

    5 5 2

    1 2 1

    2 3 2

    3 4 1

    4 5 4

    5 1 1

    1

    2

    样例输出 Sample Output

    4

    10

    时间限制

    各个测试点1s

    【样例说明】

    第一个询问:(1,2)、(1,5)、(2,5)、(3,4)。其中(2,5)的具体走法为:2-1-5

    第二个询问:(1,2)、(1,3)、(1,4)、(1,5)、(2,3)、(2,4)、(2,5)、(3,4)、(3,5)、(4,5)。其中(4,5)的具体走法为:4-3-2-1-5

    【数据规模】

    对于20%的数据满足n<=20,m<=40,Q<=40;

    对于40%的数据满足n<=1000,m<=2000,Q<=1000;

    对于60%的数据满足n<=3000,m<=6000,Q<=200000;

    对于100%的数据满足n<=100 000,m<=200 000,Q<=200 000。其他数不超过10^9。

    【细节提示】

    1 给出的n个景点不一定全部互相连通,且两个景点之间可能存在多条道路,也可能存在某条边是从某景点出发回到他自己。

    2 对于询问的结果可能很大,请注意使用适当的类型存储。

     

     

    他就是一个不完全的生成树。

    不要拿最短路做,因为,只要这条路上最大的那条边是小于忍耐度的,就可以过去,而不要求总和最小。

    然后就是 Kruskal 的并查集了,这里对并查集的应用有点像银河英雄传说(NOI)。

     

    然后,这里对这些询问的处理是静态的,先处理比较大的询问,在处理比较小的(读入后排序),因为,如果一条边在比较小的询问中可以走,那再比较大的询问中还是可以走,这样就不用重复计算了,可以拿一个 ans 值,不断地往上加。

    主要方法是,如果一条边可以走,就把这条边加进集合(并查集),然后,当不能加入集合的时候,也就是他的两个端点都在集合中的时候,此时,集合中应该包含两个联通块,这样的话,只需要把这两个联通块(显然是一个树)的根节点连起来,这样的话,两个联通块中的点就都可以互相到达了,乘法原理。

     

    代码 (ZSZ

    program foreverzsz;

    type list=record

           l,r,len:longint;

         end;

    var e:array[0..200000] of list;

        max:array[0..200000] of longint;

        num,root:array[0..200000] of longint;

        n,m,q,i,top,tot,a,b,c,fa,fb:longint;

        sum:int64;

        fuck,d:array[0..200000] of int64;

    function getfather(x:longint):longint;

    var fa:longint;

    begin

      if root[x]=x then exit(x);

      fa:=root[x];

      root[x]:=getfather(fa);

      exit(root[x]);

    end;

    procedure qs(l,r:longint);

    var i,j,x:longint;

        y:list;

    begin

      i:=l;j:=r;x:=e[(l+r)>>1].len;

      repeat

        while e[i].len<x do inc(i);

        while e[j].len>x do dec(j);

        if i<=j then

          begin

            y:=e[i];

            e[i]:=e[j];

            e[j]:=y;

            inc(i);dec(j);

          end;

      until i>j;

      if i<r then qs(i,r);

      if j>l then qs(l,j);

    end;

    procedure qs2(l,r:longint);

    var i,j,x,y:longint;

    begin

      i:=l;j:=r;x:=max[(i+j)>>1];

      repeat

        while (max[i]<x) do inc(i);

        while (max[j]>x) do dec(j);

        if i<=j then

          begin

            y:=max[i];

            max[i]:=max[j];

            max[j]:=y;

            y:=num[i];

            num[i]:=num[j];

            num[j]:=y;

            inc(i);

            dec(j);

          end;

      until i>j;

      if i<r then qs2(i,r);

      if j>l then qs2(l,j);

    end;

    procedure qs3(l,r:longint);

    var i,j,x,y:longint;

        yy:int64;

    begin

      i:=l;j:=r;x:=num[(i+j)>>1];

      repeat

        while num[i]<x do inc(i);

        while num[j]>x do dec(j);

        if i<=j then

          begin

            y:=num[i];

            num[i]:=num[j];

            num[j]:=y;

            yy:=fuck[i];

            fuck[i]:=fuck[j];

            fuck[j]:=yy;

            inc(i);

            dec(j);

          end;

      until i>j;

      if i<r then qs3(i,r);

      if j>l then qs3(l,j);

    end;

     

    begin

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

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

      readln(n,m,q);

      for i:= 1 to n do

        begin

          root[i]:=i;

          d[i]:=1;

        end;

      tot:=0;

      for i:= 1 to m do

        begin

          readln(a,b,c);

          if a<>b then

            begin

              inc(tot);

              e[tot].l:=a;e[tot].r:=b;e[tot].len:=c;

            end;

        end;

      qs(1,tot);

      for i:= 1 to q do

        begin

          read(max[i]);

          num[i]:=i;

        end;

      qs2(1,q);

      top:=1;

      sum:=0;

      for i:= 1 to q do

        begin

          while (e[top].len<=max[i])and(top<=tot) do

            begin

              fa:=getfather(e[top].l);

              fb:=getfather(e[top].r);

              if fa<>fb then

                begin

                  sum:=sum+d[fa]*d[fb];

                  root[fa]:=fb;

                  d[fb]:=d[fb]+d[fa];

                end;

              inc(top);

            end;

           fuck[i]:=sum;

         end;

       qs3(1,q);

       for i:= 1 to q do

         writeln(fuck[i]);

     

       close(input);

       close(output);

    end.

  • 相关阅读:
    【转】Asp.net页面的生命周期
    指定.net的httprequest http协议版本为1.0
    查看oracle中被锁的对象(表...)
    网友整理的Flex开源项目
    oracle中用profile限定用户资源
    (转)让你受益终身的10个Word实用技巧
    磁盘阵列卡
    Nmap扫描器的使用
    最简单的数据库连接,asp连接access数据库
    网络经典命令行
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2219008.html
Copyright © 2011-2022 走看看