码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1601 Usaco 灌水

时间:2017-09-08 20:40:15      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:names   str   space   const   get   algorithm   bsp   cost   i++   

感觉像是一道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 灌水

标签:names   str   space   const   get   algorithm   bsp   cost   i++   

原文地址:http://www.cnblogs.com/OIerLYF/p/7496105.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!