標籤:
Description
童年的我們,將和朋友分享美好的事物作為自己的快樂。這天,C小朋友得到了Plenty of candies,將要把這些糖果分給要好的朋友們。已知糖果從一個人傳給另一個人需要1 秒的時間,同一個小朋友不會重複接受糖果。由於糖果足夠多,如果某時刻某小朋友接受了糖果,他會將糖果分成若干份,分給那些在他身旁且還沒有得到糖果的小朋友們,而且自己會吃一些糖果。由於嘴饞,小朋友們等不及將糖果發完,會在得到糖果後邊吃邊發。每個小朋友從接受糖果到吃完糖果需要m秒的時間。那麼,如果第一秒C小朋友開始發糖,第多少秒所有小朋友都吃完了糖呢? 輸入格式Input Format 第一行為三個數n、p、c,為小朋友數、關係數和C小朋友的編號。
第二行為一個數m,表示小朋友吃糖的時間。
Input
第一行為三個數n、p、c,為小朋友數、關係數和C小朋友的編號。
第二行為一個數m,表示小朋友吃糖的時間。
下面p行每行兩個整數,表示某兩個小朋友在彼此身旁
Output
一個數,為所有小朋友都吃完了糖的時間
Sample Input
4 3 1
2
1 2
2 3
1 4
Sample Output
5
Hint
40%的資料滿足:1<=n<=100
60%的資料滿足:1<=n<=1000
100%的資料滿足:1<=n<=100000
m<=n*(n-1)/2,不會有同一個關係被描述多次的情況。
思路:
題目的真相是找到一條最長的最小代價路,資料之大spfa無疑。在所有的最短路中找到一條最長路保證所有的孩子都拿到糖,注意最後加上吃糖的時間。路是雙向的,被坑地蛋碎一地。
原始碼/pas:
typerec=record x,y,w,next:longint;end;var n,m,time,p:longint; g:array[1..2000000]of rec; ls,d:array[1..100000]of longint; state:array[1..100000]of longint; v:array[1..100000]of boolean; max:int64;procedure init;var i:longint;begin readln(n,m,p); readln(time); for i:=1 to n do ls[i]:=0; for i:=1 to m do begin with g[i*2-1] do begin read(x,y); w:=1; next:=ls[x]; ls[x]:=i*2-1; end; with g[i*2] do begin w:=1; x:=g[i*2-1].y; y:=g[i*2-1].x; next:=ls[x]; ls[x]:=i*2; end; end;end;procedure spfa;var head,tail,t:longint;begin head:=0; tail:=1; fillchar(state,sizeof(state),0); fillchar(v,sizeof(v),false); fillchar(d,sizeof(d),$7f div 2); d[p]:=0; state[1]:=p; v[p]:=true; repeat inc(head); t:=ls[state[head]]; while t>0 do with g[t] do begin if d[x]+w<d[y] then begin d[y]:=d[x]+w; if not v[y] then begin v[y]:=true; inc(tail); state[tail]:=y; end; end; t:=next; end; v[state[head]]:=false; until head>=tail; max:=0; for t:=2 to n do if d[t]>max then max:=d[t]; writeln(max+time+1);end;begin init; spfa;end.
分糖果_解題報告_SSL2339_tyvj1083_spfa