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

来源:互联网 发布:pp助手无法使用网络 编辑:程序博客网 时间:2024/04/28 08:41

   

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

     

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