雀巢咖啡杯~.~(二) 難得感覺到了最短路的神奇

   

       同樣大萎的.......第二試,打裸的程序比一試更令人#.#

     

     第一題題意是給出n個集合,第i個集合的元素自然數y滿足y= s[i]+k*d[i] ,k屬於自然數集, 且y<= e[i],滿足每個集合的個數的總數不超過10^8, n 不超過200000, e不超過10^9 個,保證有唯一一個數n個集合中出現奇數次,要求找出這個數;

     算法是好想的, 奇數只有一個,二分要求的數,o(m)求出在區間【1,m】的數的和,並判奇偶就行了。

     當然,亦可以ws的把集合中的數xor 起來.............


    第三題不解釋了............

 ============================以上的都是not important 的===================================


       給定一個V<=1000 E<=v^2 的無向圖,要求你在圖中選取若V-1條邊,構成一棵樹,使得在樹中每個節點到1節點的最短距離,等於該節點在原圖中到1節點的最短距離相同,並問構造的方案數。

       記得曾經一道最小生成樹計數,讓me 感受到了kruscal 最小生成樹的美妙性質。

       其實,最短路和最小生成樹..............意會吧,大家都懂的。

       最短路的性質也很美妙,首先,把dijstra 決策的邊弄出來,是一個樹(考場上一直在糾結樹怎麼構造....@.@),

而且,已經標記永久化的節點,所有的東西都確定了,其他的節點不管怎麼亂搞都不會對它有影響了。

       所以,處理一下dijstra,在標記永久化i點的時候/順便求一下/有幾條邊連向i的邊/可以在到達i的最短路上(繞口),在用乘法原理統計之...............

        

      繼續陶醉ing..............

  貼個代碼吧:

program lmd;
const mo=1 shl 31-1;
var
   c,next,l,sum:array[0..1000000]of longint;
   dist,way:array[0..3000]of longint;
   yes:array[0..3000]of boolean;
   k,i,j,bj,x,y,z,n,m,top:longint;
   ans:int64;
procedure inf;
begin
    assign(input,'castle.in');
    assign(output,'castle.out');
    reset(input); rewrite(output);
end;
procedure ouf;
begin
     close(Input); close(output);
end;
procedure link(x,y,z:longint);
begin
   inc(top);
   next[top]:=l[x];
   l[x]:=top;
   sum[top]:=y;
   c[top]:=z;
end;
procedure init;
begin
     read(n,m);
     for i:=1 to m do
        begin
           read(x,y,z);
           link (x,y,z);
           link (y,x,z);
        end;
     fillchar(dist,sizeof(dist),127);
     fillchar(yes,sizeof(yes),true);
     dist[1]:=0;
     way[1]:=1;
end;
procedure dijstra;
begin
    for i:=1 to n do
      begin
         bj:=0;
         for j:=1 to n do
          if yes[j] and (dist[j]<dist[bj]) then
            bj:=j;
         yes[bj]:=false;
         if bj<>0then
           begin
              k:=l[bj];
              while k<>0 do
                begin
                  if dist[sum[k]]>dist[bj]+c[k] then
                    begin
                      dist[sum[k]]:=dist[bj]+c[k];
                      way[sum[k]]:=1;
                    end
                  else if  dist[sum[k]]=dist[bj]+c[k] then
                     inc(way[sum[k]],1);
                  k:=next[k];
                end;
           end;
      end;
end;
procedure print;
begin
   ans:=1;
   for i:=1 to n do
     ans:=(ans*way[i]) mod mo;
   write(ans);
end;
begin
   inf; init;
   dijstra;
   print;
   ouf;
end.                              


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章