首页 > 其他 > 详细

[USACO08OCT] Watering Hole G

时间:2020-03-14 10:06:07      阅读:66      评论:0      收藏:0      [点我收藏+]

\(n\) 个牧场,需要引水灌溉,第 \(i\) 号牧场挖井需要 \(w_i\),连接 \(i,j\) 的管道需要 \(p_{i,j}\),求对所有牧场实施灌溉的最小代价方案。\(n \leq 300\)

Solution

难度:L2

设虚点 \(n+1\) 表示井水,然后连接所有边跑最小生成树即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 305;
int n,w[N],p[N][N],fa[N],ind;

struct edge {
    int u,v,w;
    bool operator < (const edge &b) {
        return w<b.w;
    }
} e[N*N*2];

int find(int p) {
    return fa[p]==p?p:fa[p]=find(fa[p]);
}
void merge(int p,int q) {
    p=find(p); q=find(q);
    if(p!=q) fa[p]=q;
}

signed main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n+1;i++) fa[i]=i;
    for(int i=1;i<=n;i++) cin>>w[i];
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            cin>>p[i][j];
        }
    }
    for(int i=1;i<=n;i++) e[++ind]={n+1,i,w[i]};
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            if(i==j) continue;
            e[++ind]={i,j,p[i][j]};
        }
    }
    sort(e+1,e+ind+1);
    int ans=0;
    for(int i=1;i<=ind;i++) {
        edge &ed=e[i];
        if(find(ed.u)!=find(ed.v)) {
            ans+=ed.w;
            merge(ed.u,ed.v);
        }
    }
    cout<<ans;
}

[USACO08OCT] Watering Hole G

原文:https://www.cnblogs.com/mollnn/p/12490455.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!