P1550 [USACO08OCT]打井Watering Hole

题目传送门

晚上闲游洛谷,偶然发现这道绿色的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;
}

  

猜你喜欢

转载自www.cnblogs.com/szmssf/p/10989191.html