Live2d Test Env

[USACO08OCT]:打井Watering Hole(MST)

题意:有N个牧场,每个牧场修水井花费Wi,连接牧场花费Pij,问最小花费,使得每个牧场要么有水井,要么和有水井的牧场有通道。

思路:加一个格外的节点O,连接O表示修井,边权是修井的费用。     那么这N+1个点求最MST即可。

刘同学想到的解法: 先找到修井费用最低的的牧场,然后和上面一样,由于最低的那个必选,所以异曲同工。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=310;
const int maxm=maxn*maxn;
int fa[maxn],t[maxn],a[maxn][maxn],tot;
struct in{
    int len,u,v;
}s[maxm];
bool cmp(in w,in q) {
    return w.len<q.len;
}
void add(int u,int v,int len){
    tot++; s[tot].u=u; s[tot].v=v; 
    s[tot].len=len;
}
int find(int x){
    if(x!=fa[x]) return fa[x]=find(fa[x]);
    return x;
}
int main()
{
    int N,M,ans=0;
    scanf("%d",&N);
    rep(i,1,N) scanf("%d",&t[i]);
    rep(i,1,N) rep(j,1,N) {
        scanf("%d",&a[i][j]);
        if(a[i][j]) add(i,j,a[i][j]);
    }
    rep(i,0,N) fa[i]=i;
    rep(i,1,N) add(0,i,t[i]);
    sort(s+1,s+tot+1,cmp);
    rep(i,1,tot) {
        int fu=find(s[i].u);
        int fv=find(s[i].v);
        if(fu==fv) continue;
        fa[fu]=fv; ans+=s[i].len;
     }
     printf("%d\n",ans);
    return 0;
}

 

posted @ 2019-07-10 16:18  nimphy  阅读(327)  评论(0编辑  收藏  举报