版权声明:本文为博主原创文章,未经博主允许可以转载,但要注明出处 https://blog.csdn.net/wang3312362136/article/details/84236971
题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=1601
题解
在一块土地上建造水库,相当于从一个有水的0号水库引水,做一遍最小生成树即可。
代码
#include <cstdio>
#include <algorithm>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=300;
const int maxm=50000;
struct edge
{
int x,y,l;
edge(int _x=0,int _y=0,int _l=0):x(_x),y(_y),l(_l){}
bool operator <(const edge &other) const
{
return l<other.l;
}
};
edge e[maxm+10];
int n,m,ans;
namespace dsu
{
int fa[maxn+10];
int clear()
{
for(int i=0; i<=n; ++i)
{
fa[i]=i;
}
return 0;
}
int find(int x)
{
return (fa[x]==x)?x:(fa[x]=find(fa[x]));
}
};
int main()
{
n=read();
for(int i=1; i<=n; ++i)
{
int x=read();
e[++m]=edge(0,i,x);
}
for(int i=1; i<=n; ++i)
{
for(int j=1; j<i; ++j)
{
int x=read();
e[++m]=edge(i,j,x);
}
for(int j=i; j<=n; ++j)
{
read();
}
}
std::sort(e+1,e+m+1);
dsu::clear();
for(int i=1,cnt=0; cnt<n; ++i)
{
int x=dsu::find(e[i].x),y=dsu::find(e[i].y);
if(dsu::fa[x]!=dsu::fa[y])
{
dsu::fa[x]=y;
++cnt;
ans+=e[i].l;
}
}
printf("%d\n",ans);
return 0;
}