1. 程式人生 > >BZOJ 1601 Usaco 灌水

BZOJ 1601 Usaco 灌水

oid scan struct logs 動作 amp algorithm mst turn

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