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 灌水的主要内容,如果未能解决你的问题,请参考以下文章