*【bzoj 1601】灌水(最小生成树)

来源:互联网 发布:趋势操盘软件 编辑:程序博客网 时间:2024/06/06 00:50

传送门biu~
建一个虚拟0号节点,0号节点到各个节点的权为在这个节点建造水库的花费,显然跑一遍最小生成树就是灌水的最小代价。

#include<bits/stdc++.h>#define N 305using namespace std;int n,ans;int father[N],num;int search(int x){return father[x]==x?x:father[x]=search(father[x]);}struct edge{    int x,y,len;}a[N*N];int tp;bool cmp(edge a,edge b){return a.len<b.len;}int main(){    scanf("%d",&n);    for(int i=0;i<=n;++i)       father[i]=i;    for(int i=1;i<=n;++i){        int x;        scanf("%d",&x);        ++tp;a[tp].x=0;a[tp].y=i;a[tp].len=x;    }    for(int i=1;i<=n;++i){        for(int j=1;j<=n;++j){            int x;            scanf("%d",&x);            if(i<j){                ++tp;a[tp].x=i;a[tp].y=j;a[tp].len=x;            }        }    }    sort(a+1,a+tp+1,cmp);    for(int i=1;i<=tp;++i){        int xn=search(a[i].x);        int yn=search(a[i].y);        if(xn!=yn){            father[xn]=yn;            ++num;ans+=a[i].len;            if(num==n)      break;        }    }    printf("%d",ans);    return 0;}
原创粉丝点击