今天校内测,有一道有向无环图的最长路,然后脑子发热交了spfa的,被学长思想教育了一番,学长说有向无环图最长路拓扑排序肯定是比spfa优的,然后就很傻地说我做过一题spfa更优,后来回去翻到了题,发现那是个无向图,妥妥地实力打脸。
题目描述大概是讲一群小孩分糖果,开始糖果在一个人手里,第一秒开始手上有糖的人美秒把糖分给周围的人,每个人拿到糖后都用同样C的时间吃糖(吃糖和发糖是可以同时进行的),问开始到最后一个人吃完糖要多久(人数≤10^5,关系数≤2*10^6,保证不重复)
显然,答案是最长路+C
不多说,放代码
var ans,tot,n,e,m,s,head,tail:longint;
dist,que,link:array[0..100005]of longint;
w,son,next:array[0..2000005]of longint;
vis:array[0..100005]of boolean;
procedure add(x,y,z:longint);
begin
inc(tot);w[tot]:=z;son[tot]:=y;next[tot]:=link[x];link[x]:=tot;
end;
procedure init;
var x,y,i:longint;
begin
assign(input,'candy.in');reset(input);
assign(output,'candy.out');rewrite(output);
fillchar(link,sizeof(link),0);
tot:=0;
readln(n,e,s);
readln(m);
for i:=1 to e do
begin
readln(x,y);
add(x,y,1);
add(y,x,1);
end;
end;
procedure spfa;
var xx,j:longint;
begin
fillchar(dist,sizeof(dist),63);
fillchar(vis,sizeof(vis),0);
fillchar(que,sizeof(que),0);
que[1]:=s;dist[s]:=0;vis[s]:=true;
head:=0;tail:=1;
while head<>tail do
begin
head:=(head+1) mod 100005;
xx:=que[head];
vis[xx]:=false;
j:=link[xx];
while j<>0 do
begin
if dist[xx]+w[j]<dist[son[j]] then begin
dist[son[j]]:=dist[xx]+w[j];
if not vis[son[j]] then begin
vis[son[j]]:=true;
tail:=(tail+1) mod 100005;
que[tail]:=son[j];
end;
end;
j:=next[j];
end;
end;
end;
procedure print;
var i:longint;
begin
ans:=-maxlongint;
for i:=1 to n do
if dist[i]>ans then ans:=dist[i];
writeln(ans+1+m);
close(input);close(output);
end;
begin
init;
spfa;
print;
end.
Bingo!
【写的有漏洞的,欢迎路过大神吐槽】
2016-11-6 23:16:23
Ending.