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

   

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

     

     第一题题意是给出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.                              


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