BZOJ 1601 Usaco 灌水

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1601 Usaco 灌水相关的知识,希望对你有一定的参考价值。

感觉像是一道MST的题目,但是难以处理这个自建水库的动作。
一开始想着给自己连一条边,但是判断父亲时就有Bug了。
之后想了给每个点都新建一个点,这样好处理了。但是与MST又有冲突了。
最后想了想,把自建水库的费用当作X点连向N+1点,于是1-N都与N+1有一条边,
我们只需要求一个N+1的最小生成树就可以求解了。
Orz 奶牛题目虽然是水题,但是练练思维能力还是挺好的。(大佬别吐槽我这种蒟蒻)

 

#include <cstdio>
#include <algorithm>
using namespace std;
 
int n,x,Count;
int cost,fa[305];
int Min;
 
struct node{
    int u,v,w;
    bool operator <(const node &a)const{
        return w<a.w;
    }
}Edge[100005];
 
 
int getfa(int x){
    if(x!=fa[x]) return fa[x]=getfa(fa[x]);
    return fa[x];
}
 
 
void Run(){
    for(int i=1;i<=n+1;i++) fa[i]=i;
    std::sort(Edge+1,Edge+1+Count); 
    for(int i=1;i<=Count;i++){
        node &now = Edge[i];
        int fx = getfa(Edge[i].u);
        int fy = getfa(Edge[i].v);
        if(fx!=fy){
            //printf("Edge:%d %d %d Min:%d\n",now.u,now.v,now.w,Min);
            Min+=now.w;
            fa[fy]=fx;
        }
    }   
}
 
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        Count++;
        scanf("%d",&cost);
        Edge[Count].u=n+1;
        Edge[Count].v=i;
        Edge[Count].w=cost;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            Count++;
            scanf("%d",&x);
            Edge[Count].u=i;
            Edge[Count].v=j;
            Edge[Count].w=x;
    }
    Run();
    printf("%d\n",Min);
}

 

以上是关于BZOJ 1601 Usaco 灌水的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ——1601: [Usaco2008 Oct]灌水

Bzoj1601 [Usaco2008 Oct]灌水

BZOJ1601 [Usaco2008 Oct]灌水

BZOJ 1601 USACO 2008 Oct. 灌水

bzoj1601: [Usaco2008 Oct]灌水

BZOJ 1601 [Usaco2008 Oct]灌水:最小生成树