同樣大萎的.......第二試,打裸的程序比一試更令人#.#
第一題題意是給出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.