bzoj 1601 最小生成树

原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1601

最小生成树的比较水的题,我们只需要加一个源点,连向所有的点,边权为每个点建水库的代价

/**************************************************************
    Problem: 1601
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:216 ms
    Memory:3744 kb
****************************************************************/
 
//By BLADEVIL
var
    n                       :longint;
    pre, other, len         :array[0..300020] of longint;
    tot                     :longint;
    father                  :array[0..500] of longint;
    ans                     :longint;
     
procedure swap(var  a,b:longint); 
var
    c                       :longint;
begin
    c:=a; a:=b; b:=c;
end;
     
procedure qs(low,high:longint);
var
    i, j, x                 :longint;
begin
    i:=low; j:=high; x:=len[(i+j) div 2];
    while i<j do
    begin
        while len[i]<x do inc(i);
        while len[j]>x do dec(j);
        if i<=j then
        begin
            swap(len[i],len[j]);
            swap(pre[i],pre[j]);
            swap(other[i],other[j]);
            inc(i); dec(j);
        end;
    end;
    if i<high then qs(i,high);
    if j>low then qs(low,j);
end;
     
     
procedure init;
var
    i, j                    :longint;
    x                       :longint;
     
begin
    read(n);
    for i:=1 to n do
    begin
        inc(tot);
        pre[tot]:=n+1;
        other[tot]:=i;
        read(len[tot]);
    end;
    for i:=1 to n do
        for j:=1 to n do
        if i<>j then
        begin
            inc(tot);
            pre[tot]:=i;
            other[tot]:=j;
            read(len[tot]);
        end else read(x);
    qs(1,tot);
end;
 
function getfather(x:longint):longint;
begin
    if father[x]=x then exit(x);
    father[x]:=getfather(father[x]);
    exit(father[x]);
end;
 
procedure main;
var
    i                       :longint;
    x, y, fx, fy            :longint;
     
begin
    for i:=1 to n+1 do father[i]:=i;
    for i:=1 to tot do
    begin
        x:=pre[i]; y:=other[i];
        fx:=getfather(x);
        fy:=getfather(y);
        if fx<>fy then
        begin
            inc(ans,len[i]);
            father[fx]:=fy;
        end;
    end;
    writeln(ans);
end;
 
begin
    init;
    main;
end.

 

posted on 2013-11-22 07:26  BLADEVIL  阅读(172)  评论(0编辑  收藏  举报