晚上闲游洛谷,偶然发现这道绿色的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; }
P1550 [USACO08OCT]打井Watering Hole
原文:https://www.cnblogs.com/szmssf/p/10989191.html