BZOJ_1601_[Usaco2008_Oct]_灌水_(最小生成树_Kruskal)

Posted 晴歌。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ_1601_[Usaco2008_Oct]_灌水_(最小生成树_Kruskal)相关的知识,希望对你有一定的参考价值。

描述


http://www.lydsy.com/JudgeOnline/problem.php?id=1601

有\\(n\\)个田地需要灌溉,每个田地可以自己引水,花费为\\(w[i]\\),或者连接其他被灌溉的田地,花费为\\(p[i][j]\\),求最小花费.

 

分析


我第一眼看以为是dp,发现不对...

如果田地不能自己引水只能和其他田地连接,就是裸的最小生成树.

这里加了一个可以自己引水,相当于加了一个和所有点都有连边,且权值分别为\\(w[i]\\)的结点,然后求\\(n+1\\)个点的最小生成树即可.

 

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn=300+5;
 5 struct edge{
 6     int u,v,w;
 7     edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
 8     bool operator < (const edge &a) const { return w<a.w; }
 9 }g[maxn*maxn];
10 int n,ect,ans;
11 int f[maxn];
12 inline int read(int &x){ x=0;int k=1;char c;for(c=getchar();c<\'0\'||c>\'9\';c=getchar())if(c==\'-\')k=-1;for(;c>=\'0\'&&c<=\'9\';c=getchar())x=x*10+c-\'0\';return x*=k; }
13 inline int find(int x){ return x==f[x]?x:f[x]=find(f[x]); }
14 int main(){
15     read(n);
16     for(int i=1,w;i<=n;i++) g[++ect]=edge(0,i,read(w)), f[i]=i;
17     for(int i=1;i<=n;i++)for(int j=1,w;j<=n;j++){
18         read(w);
19         if(j<i) g[++ect]=edge(i,j,w);
20     }
21     sort(g+1,g+ect+1);
22     for(int i=1,j=n;i<=ect&&j;i++){
23         int fu=find(g[i].u),fv=find(g[i].v);
24         if(fu!=fv) f[fu]=fv, j--, ans+=g[i].w;
25     }
26     printf("%d\\n",ans);
27     return 0;
28 }
View Code

 

 

 

 

以上是关于BZOJ_1601_[Usaco2008_Oct]_灌水_(最小生成树_Kruskal)的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ1601][Usaco2008 Oct]灌水

BZOJ——1601: [Usaco2008 Oct]灌水

BZOJ1601 [Usaco2008 Oct]灌水

Bzoj1601 [Usaco2008 Oct]灌水

bzoj1601: [Usaco2008 Oct]灌水

BZOJ1601: [Usaco2008 Oct]灌水