bzoj 1601 最小生成树经典题

题意:n块农田,全部灌水。有两种方式:(1)在第n块天上花费wi建造一个水库(2)从另一块田j花费Pij引水,求最小花费

MST好题

如果没有可以建造水库的条件,那么就是一个最小生成树,没毛病╮(╯_╰)╭

然而加上这个条件以后,相当于可以自己向自己引水花费为wi

加一个超级源点,并向n个点连边为wi,然后对这n+1个点跑最小生成树即可

编程难度为0,但是想到超级源点的难度还是不小的,超级源点在MST、网络流、差分约束系统...应用还是满广的还很灵活

type
        rec=record
            a,b,len:longint;
end;

var
        n,m,ta,tb,ans   :longint;
        ss,tt           :longint; 
        f               :array[0..90010] of longint;
        l               :array[0..50010] of rec;
        i,j             :longint;
        map             :array[0..310,0..310] of longint;
function get_father(x:longint):longint;
begin
   if x=f[x] then exit(x);
   f[x]:=get_father(f[x]);
   exit(F[x]);
end;

procedure sort(ll,rr:longint);
var
        i,j:longint;
        x:longint;
        y:rec;
begin
   i:=ll; j:=rr; x:=l[(ll+rr)>>1].len;
   while (i<=j) do
   begin
      while l[i].len<x do inc(i);
      while l[j].len>x do dec(j);
      if (i<=j) then
      begin
         y:=l[i]; l[i]:=l[j]; l[j]:=y;
         inc(i); dec(j);
      end;
   end;
   if i<rr then sort(i,rr);
   if j>ll then sort(ll,j);
end;

begin
   read(n); ss:=n+1;
   for i:=1 to n+1 do f[i]:=i;
   for i:=1 to n do
   begin
      read(l[i].len);
      l[i].a:=ss; l[i].b:=i;
   end;
   m:=n;
   for i:=1 to n do
     for j:=1 to n do read(map[i,j]);
   for i:=1 to n do
     for j:=i+1 to n do
     begin
        inc(m);
        l[m].len:=map[i,j];
        l[m].a:=i; l[m].b:=j;
     end;
   sort(1,m);
   tt:=0;
   for i:=1 to m do
   begin
      ta:=get_father(l[i].a);
      tb:=get_father(l[i].b);
      if (ta<>tb) then
      begin
         inc(tt);
         f[ta]:=tb;
         inc(ans,l[i].len);
         if tt=n then break;
      end;
   end;
   writeln(ans);
end.
——by EIrlys



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值