bzoj1638[Usaco2007 Mar]Cow Traffic (first code)

求出走到每个点有的方法数a[i],再求出每个点到终点的方法数b[i]。 每条边走的 次数=a[u[i]]*b[v[i]] 。 可以用类spfa按照拓扑序求a[i],把入度为0的点都入栈然后a[e[j]]=a[e[j]]+a[q[h]] 求b[i]可以把边反向重新spfa一遍。 [toggle Title="code "] [pascal] uses math; var u,v,rud,next,e,head:Array[1..50000]of longint; f,ff:array[1..50000]of int64; ans:int64; i,j,n,m,ee,h,t:longint; a:array[1..100000]of longint; procedure swap(var aa,bb:longint); var tt:longint; begin tt:=aa;aa:=bb;bb:=tt; end; procedure add(u,v:longint); begin inc(ee);next[ee]:=head[u];head[u]:=ee;e[ee]:=v; end; begin readln(n,m); for i:=1 to m do begin readln(u[i],v[i]); if u[i]>v[i] then swap(u[i],v[i]); add(u[i],v[i]); inc(rud[v[i]]); end; h:=1; t:=0; for i:=1 to n do if rud[i]=0 then begin inc(t);a[t]:=i;f[i]:=1; end; while h<=t do begin j:=head[a[h]]; while j<>0 do begin f[e[j]]:=f[e[j]]+f[a[h]]; dec(rud[e[j]]); if rud[e[j]]=0 then begin inc(t);a[t]:=e[j]; end; j:=next[j]; end; inc(h); end; fillchar(head,sizeof(head),0);ee:=0; fillchar(rud,sizeof(rud),0); for i:=1 to m do begin add(v[i],u[i]); inc(rud[u[i]]); end; h:=1; t:=0; for i:=1 to n do if rud[i]=0 then begin inc(t);a[t]:=i;ff[i]:=1; end; while h<=t do begin j:=head[a[h]]; while j<>0 do begin ff[e[j]]:=ff[e[j]]+ff[a[h]]; dec(rud[e[j]]); if rud[e[j]]=0 then begin inc(t);a[t]:=e[j]; end; j:=next[j]; end; inc(h); end; for i:=1 to m do if f[u[i]]*ff[v[i]]>ans then ans:=f[u[i]]*ff[v[i]]; writeln(ans); end. [/pascal] [/toggle]
posted @ 2013-03-19 15:53  lbz007  阅读(131)  评论(0编辑  收藏  举报
Live2D