题意:给定N个字符串,如果A串的最后两个字母跟B串的前两个字母相同它们就能连接。
求一个由字符串组成的首尾相连的环,使(字符串总长度/字符串个数)最大。
n<=100000 len<=1000
思路:SPFA国家队论文题
赋所有dis[i]=0,跑最长路,如果某个元素入队次数超过点数就说明有正环。
使用DFS版本的SPFA做比BFS快10倍,为什么?
论文里高大上看不懂,蒟蒻用简单粗暴的方法想了一下:
如果某个环有K个点组成,BFS会从K个点中的某个点开始,每次都换一个点扩展一次,可能达到O(N*K^2)
DFS则只选其中的一个点不断扩展,K次就能使自己重新入队一次,这样就是O(N*K)
孰优孰劣一眼分明
以下是论文原文,用来证明初始值=0的正确性
1 var q:array[0..2000000]of longint; 2 dis:array[1..2000]of double; 3 head,vet,next,len,time,inq:array[1..150000]of longint; 4 n,m,tot,i,x,y,k:longint; 5 l,r,mid,last,eps:double; 6 ch:ansistring; 7 8 procedure add(a,b,c:longint); 9 begin 10 inc(tot); 11 next[tot]:=head[a]; 12 vet[tot]:=b; 13 len[tot]:=c; 14 head[a]:=tot; 15 end; 16 17 function spfa(k:double):boolean; 18 var u,top,i,e,v:longint; 19 begin 20 top:=0; 21 for i:=1 to 27*27 do 22 begin 23 inq[i]:=0; dis[i]:=0; time[i]:=0; 24 end; 25 for i:=1 to 27*27 do 26 if head[i]>0 then 27 begin 28 inc(top); q[top]:=i; inq[i]:=1; inc(time[i]); 29 end; 30 while top>0 do 31 begin 32 u:=q[top]; dec(top); 33 inq[u]:=0; 34 e:=head[u]; 35 while e<>0 do 36 begin 37 v:=vet[e]; 38 if dis[u]+len[e]-k>dis[v] then 39 begin 40 dis[v]:=dis[u]+len[e]-k; 41 if inq[v]=0 then 42 begin 43 inc(top); q[top]:=v; inq[v]:=1; 44 inc(time[v]); 45 if time[v]>n then exit(true); 46 end; 47 end; 48 e:=next[e]; 49 end; 50 end; 51 exit(false); 52 end; 53 54 begin 55 assign(input,'poj2949.in'); reset(input); 56 assign(output,'poj2949.out'); rewrite(output); 57 while not eof do 58 begin 59 readln(n); 60 if n=0 then exit; 61 fillchar(head,sizeof(head),0); tot:=0; 62 for i:=1 to n do 63 begin 64 readln(ch); k:=length(ch); 65 x:=(ord(ch[1])-ord('a'))*27+ord(ch[2])-ord('a')+1; 66 y:=(ord(ch[k-1])-ord('a'))*27+ord(ch[k])-ord('a')+1; 67 add(x,y,k); 68 end; 69 n:=0; 70 for i:=1 to 27*27 do 71 if head[i]>0 then inc(n); 72 l:=0; r:=1000; last:=0; 73 eps:=1e-5; 74 while r-l>eps do 75 begin 76 mid:=(l+r)/2; 77 if spfa(mid) then begin last:=mid; l:=mid; end 78 else r:=mid; 79 end; 80 if last<eps then writeln('No solution.') 81 else writeln(last:0:2); 82 83 end; 84 close(input); 85 close(output); 86 end.