BZOJ1601: [Usaco2008 Oct]灌水

最小生成树

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define pb push_back
#define MAXN 300+10
using namespace std;
struct Edge{
    int from,to,cost;
    Edge(int x=0,int y=0,int c=0){
        from=x,to=y,cost=c;
    }
    friend bool operator < (const Edge &p1,const Edge &p2){
        return (p1.cost<p2.cost);
    }
};
vector<Edge> vs;
int n;
int f[MAXN];
int find(int x){
    return (f[x]==x?x:f[x]=find(f[x]));
}    
void lik(int x,int y){
    x=find(x),y=find(y);
    if(x!=y){
        f[x]=y;
    }
}
bool same(int x,int y){
    return (find(x)==find(y));
}
void init(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int v;scanf("%d",&v);
        vs.pb(Edge(0,i,v));
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            int v;scanf("%d",&v);
            if(i<=j)continue;
            vs.push_back(Edge(i,j,v));
        }
    }
    for(int i=1;i<=n;i++){
        f[i]=i;
    }
}
void solve(){
    sort(vs.begin(),vs.end());
    int ans=0;
    for(int i=0;i<vs.size();i++){
        int x=vs[i].from,y=vs[i].to,c=vs[i].cost;
        if(!same(x,y)){
            lik(x,y);
            ans+=c;
        }
    }
    printf("%d\n",ans);
}
int main()
{
    init();
    solve();
    return 0;
}    

 

posted @ 2017-12-19 13:40  white_hat_hacker  阅读(103)  评论(0编辑  收藏  举报