图论基础_最小生成树

1.Prim算法(POJ2560)

const maxn=101;
var   x,y,mindis:array[0..maxn] of extended;
      dis:array[0..maxn,0..maxn] of extended;
      vis:array[0..maxn] of boolean;
      n,i,j:longint;

      function calc(a,b:longint):extended;
      begin
            calc:=sqrt(sqr(x[a]-x[b])+sqr(y[a]-y[b]));
      end;

      procedure prim(root:longint);
      var   i,j,k:longint;
            min,sum:extended;
      begin
            sum:=0;
            fillchar(vis,sizeof(vis),0);
            vis[root]:=true;
            for i:=1 to n do mindis[i]:=dis[i,root];
            for i:=1 to n-1 do
            begin
                  min:=1e100;
                  for j:=1 to n do
                  if (not vis[j])and(mindis[j]<min) then
                  begin
                        min:=mindis[j];
                        k:=j;
                  end;
                  vis[k]:=true;
                  sum:=sum+min;
                  for j:=1 to n do
                  if (not vis[j])and(dis[j,k]<mindis[j]) then
                    mindis[j]:=dis[j,k];
            end;
            writeln(sum:0:2);
      end;


begin
      readln(n);
      for i:=1 to n do readln(x[i],y[i]);
      for i:=1 to n-1 do
         for j:=i+1 to n do
         begin
               dis[i,j]:=calc(i,j);
               dis[j,i]:=dis[i,j];
         end;

      Prim(1);
end.

2.Kruskal算法(POJ2485)

type  node=record
      u,v,w:longint;
end;
const oo=1000000;
var   e:array[0..260000] of node;
      f:array[0..510] of longint;
      n,d,datanum:longint;


      procedure sort(l,r:longint);
      var   i,j,mid:longint;
            temp:node;
      begin
            i:=l; j:=r;
            mid:=e[(l+r)>>1].w;
            repeat
                   while e[i].w<mid do inc(i);
                   while e[j].w>mid do dec(j);
                   if i<=j then
                   begin
                         temp:=e[i];
                         e[i]:=e[j];
                         e[j]:=temp;
                         inc(i); dec(j);
                   end;
            until i>j;
            if i<r then sort(i,r);
            if j>l then sort(l,j);
      end;

      procedure init;
      var   i,j,weight,ecount:longint;
      begin
            readln;
            readln(n);
            ecount:=0;
            for i:=1 to n do
            begin
                  for j:=1 to n do
                  begin
                       read(weight);
                       inc(ecount);
                       if weight=0 then weight:=oo;
                       e[ecount].w:=weight;
                       e[ecount].u:=i;
                       e[ecount].v:=j;
                  end;
                  readln;
            end;
            sort(1,n*n);
      end;

      function getf(x:longint):longint;
      begin
            if f[x]<>x then f[x]:=getf(f[x]);
            exit(f[x]);
      end;

      procedure union(u,v:longint);
      begin   f[u]:=v;   end;

      function kruskal:longint;
      var   i,count,max:longint;
      begin
            for i:=1 to n do f[i]:=i;
            count:=0;    max:=-oo;
            for i:=1 to n*n do
            begin
                  if count=n-1 then break;
                  if (getf(e[i].u)<>getf(e[i].v)) then
                  begin
                        inc(count);
                        if e[i].w>max then max:=e[i].w;
                        union(getf(e[i].u),getf(e[i].v));
                  end;
            end;
            exit(max);
      end;


begin
      readln(datanum);
      for d:=1 to datanum do
      begin
            init;
            writeln(kruskal);
      end;
end.

转载于:https://www.cnblogs.com/exponent/archive/2011/08/07/2130228.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值