section 1 生成树计数
n个节点的带标号的生成树有n^(n-2)个(根据prufer编码可证)
推广1:n个节点的度依次为D1, D2, ..., Dn的无根树共有(n-2)! / [ (D1-1)!(D2-1)!..(Dn-1)! ]个,因为此时Prüfer编码中的数字i恰好出现Di-1次。
推广2: 完全二分图Km,n有(m^(n-1)) * (n^(m-1))个不同的生成树
section 2 KMP简单应用
对于一个字符串,若要求其前缀子串与后缀子串相等的字串长度,可用kmp算法中的next数组求解,代码如下
readln(st); n:=length(st); p:=0; for i:=2 to n do begin while (p<>0) and (st[p+1]<>st[i]) do p:=next[p]; if st[p+1]=st[i] then begin inc(p); next[i]:=p; end else next[i]:=0; end; p:=n; while p<>0 do begin inc(tot); a[tot]:=p; p:=next[p]; end;
其中,st表示该字符串,n表示字符串长度,p为指针,a数组即为所求
section 3 KM算法模板
1 function dfs(u:longint):boolean; 2 var 3 j :longint; 4 begin 5 ux[u]:=true; 6 for j:=n+1 to n*2 do 7 begin 8 if (not uy[j]) and (cx[u]+cy[j]=w[u,j]) then 9 begin 10 uy[j]:=true; 11 if (link[j]=0) or (dfs(link[j])) then 12 begin 13 link[j]:=u; 14 exit(true); 15 end; 16 end; 17 end; 18 exit(false); 19 end; 20 21 function km:longint; 22 var 23 d,ans,i,j,k :longint; 24 begin 25 for k:=1 to n do 26 begin 27 while true do 28 begin 29 d:=maxlongint; 30 fillchar(ux,sizeof(ux),false); 31 fillchar(uy,sizeof(uy),false); 32 if dfs(k) then break; 33 for i:=1 to n do 34 begin 35 if ux[i] then 36 for j:=n+1 to n*2 do 37 if not uy[j] then d:=min(d,cx[i]+cy[j]-w[i,j]); 38 end; 39 for i:=1 to n do if ux[i] then dec(cx[i],d); 40 for j:=n+1 to n*2 do if uy[j] then inc(cy[j],d); 41 end; 42 end; 43 ans:=0; 44 for j:=n+1 to n*2 do 45 begin 46 if link[j]<>0 then inc(ans,w[link[j],j]); 47 end; 48 exit(ans); 49 end;