晚上闲游洛谷,偶然发现这道绿色的MST板子
首先,毫无疑问,这是一道MST的题,而重点在与这句话:“请求出农民John 需要为使所有农场都与有水的农场相连或拥有水井所需要的钱数。”
需要让所有地方都有水,但是这些农场最开始是没水的,我们需要加入一个“水源”节点,而0号节点一般在MST板子中不会有用,这成为了我们最好的选择(如果你强迫症打MST从0号到n-1号节点那你就当我什么都没说)
我们只需要让0号节点也加入进来并把MST的条件设为n条边即可,其他剩下的地方直接套MST板子,我就不打算法步骤了(其实是因为懒)
参考程序如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int u,v,w;
};
node f[100001];
int n,w,parent[305],sum,num,weight;
bool cmp(node a,node b){return a.w<b.w;}
int find(int x)
{
if(parent[x]==x)return x;
return parent[x]=find(parent[x]);
}
void Union(int u,int v)
{
int U=find(u),V=find(v);
if(U==V)return;
parent[U]=V;
}
int main()
{
cin>>n;
for(int i=0;i<=n;i++)
{
parent[i]=i;
}
for(int i=1;i<=n;i++)
{
cin>>w;
f[++sum].u=0;
f[sum].v=i;
f[sum].w=w;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>w;
if(i>j)
{
f[++sum].u=i;
f[sum].v=j;
f[sum].w=w;
}
}
}
sort(f+1,f+1+sum,cmp);
for(int i=1;i<=sum;i++)
{
int u=find(f[i].u),v=find(f[i].v);
if(u!=v)
{
weight+=f[i].w;
num++;
Union(u,v);
}
if(num==n)break;
}
cout<<weight<<endl;
return 0;
}