图论算法小结

                                                                        图论算法小结

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.
View Code

 最小生成树(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.
View Code

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.
View Code

 注意事项

1.prim边的权值可以为负

2.判断是否存在最小生成树,对于kruskal只需判断每个点祖先是否一样。

posted @ 2015-10-15 12:58  QTY_YTQ  阅读(175)  评论(0)    收藏  举报