图论算法小结
图论算法小结
noip2015要到了,复习一下基本图论。
最短路(poj2387)
SPFA
program gtrh; var w,a:array[0..1000,0..2000]of longint; q:array[0..50000]of longint; dis:array[0..1000]of longint; g:array[0..1000]of boolean; n,i,m,t,x,y,z,h,u,v:longint; function min(x,y:longint):longint; begin if x<y then min:=x else min:=y; end; begin readln(t,n); fillchar(w,sizeof(w),$7f); for i:=1 to t do begin readln(x,y,z); a[x,0]:=a[x,0]+1; a[x,a[x,0]]:=y; a[y,0]:=a[y,0]+1; a[y,a[y,0]]:=x; w[x,y]:=min(w[x,y],z); w[y,x]:=min(w[y,x],z); end; for i:=1 to n do dis[i]:=maxlongint div 3; fillchar(g,sizeof(g),false); h:=0; t:=1; dis[1]:=0; q[1]:=1; g[1]:=true; while h<t do begin h:=h+1; u:=q[h]; g[u]:=false; for i:=1 to a[u,0] do begin v:=a[u,i]; if dis[u]+w[u,v]<dis[v] then begin dis[v]:=dis[u]+w[u,v]; if g[v]=false then begin t:=t+1; q[t]:=v; g[v]:=true; end; end; end; end; writeln(dis[n]); end.
最小生成树(poj1258)
prim
program net; var a:array[0..100,0..100]of longint; dis:array[0..100]of longint; g:array[0..100]of boolean; n,i,m,j,k,s,t:longint; begin while not eof do begin readln(n); s:=0; for i:=1 to n do begin for j:=1 to n do read(a[i,j]);readln; end; fillchar(dis,sizeof(dis),$7f);fillchar(g,sizeof(g),0); dis[1]:=0; for i:=1 to n do begin k:=maxlongint; for j:=1 to n do if (dis[j]<k)and(g[j]=false) then begin k:=dis[j]; t:=j; end; g[t]:=true; for j:=1 to n do if (g[j]=false)and(a[t,j]<dis[j]) then dis[j]:=a[t,j]; end; for i:=1 to n do s:=s+dis[i]; writeln(s); end; end.
kruskal
program net; var a,b,v,f:array[0..10000]of longint; n,i,m,j,x,y,k,s:longint; procedure qsort(l,h:longint); var i,j,t,m:longint; begin i:=l; j:=h; m:=v[(i+j) div 2]; repeat while v[i]<m do inc(i); while m<v[j] do dec(j); if i<=j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; t:=b[i]; b[i]:=b[j]; b[j]:=t; t:=v[i]; v[i]:=v[j]; v[j]:=t; inc(i); dec(j); end; until i>j; if i<h then qsort(i,h); if j>l then qsort(l,j); end; function find(x:longint):longint; var i,j,k:longint; begin j:=x; i:=x; while i<>f[i] do i:=f[i]; while j<>i do begin k:=f[j]; f[j]:=i; j:=k; end; exit(i); end; begin while not eof do begin readln(n); k:=0;m:=0;s:=0; for i:=1 to n do begin for j:=1 to n do begin read(x); if i<>j then begin m:=m+1; v[m]:=x; a[m]:=i; b[m]:=j; end; end; readln; end; qsort(1,m); for i:=1 to n do f[i]:=i; for i:=1 to m do begin x:=find(a[i]); y:=find(b[i]); if x<>y then begin f[y]:=x; s:=s+v[i]; inc(k); end; if k=n-1 then break; end; writeln(s); end; end.
注意事项
1.prim边的权值可以为负
2.判断是否存在最小生成树,对于kruskal只需判断每个点祖先是否一样。

浙公网安备 33010602011771号