P1550 [USACO08OCT]Watering Hole G 最小生成树+

Farmer John 的农场缺水了。

他决定将水引入到他的 nn 个牧场。他准备通过挖若干井,并在各块田中修筑水道来连通各块田地以供水。在第 ii 号田中挖一口井需要花费 W_iWi 元。连接 ii 号田与 jj 号田需要 P_{i,j}Pi,jP_{j,i}=P_{i,j}Pj,i=Pi,j)元。

请求出 FJ 需要为使所有农场都与有水的农场相连或拥有水井所需要的最少钱数。

 

--

正解是类似于开一个超级原点这样的东西作为水井费用

评论区yy了可以在维护并查集的时候判断是分开挖好还是一起挖好。

我yy了一个在找出最小生成树后遍历一遍dfs,如果在当前集合建水井的费用小于和父节点连的边,就在当前集合建..

懒狗想建超级原点

 

复制代码
#include<bits/stdc++.h>
using namespace std;
int parent[50001],n,w[50005];
int find(int x)
{
   if(parent[x]!=x)
    {
        parent[x]=find(parent[x]);
    }
    return parent[x];
} 
struct node
{
    int from,to,d;
    bool operator < (const node&a) const
    {
        return d<a.d;
    }
}g[1000000];
int main( )
{
    int cnt=0;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>w[i];
    
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
     { 
       int dis;
       cin>>dis;
       if(i==j) continue;
       cnt++;
       g[cnt].d=dis;g[cnt].from=i;g[cnt].to=j;
     }
     
     
     for(int i=1;i<=n;i++)
     {cnt++;
         g[cnt].d=w[i];
         g[cnt].from=i;
         g[cnt].to=n+1;
     }
     sort(g+1,g+cnt+1);
     
     for(int i=1;i<=n+1;i++)
      {
          parent[i]=i;
      }
     
     int ans=0;
     
     for(int i=1;i<=cnt;i++)
     {
        int fa=find(g[i].from),fb=find(g[i].to);
        if(fa!=fb)
        {   
            parent[fa]=parent[fb];
            
            ans+=g[i].d;
            }
     }
     cout<<ans;
}
复制代码

 

posted @   liyishui  阅读(63)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示