博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Luogu P1550 [USACO08OCT]打井Watering Hole
阅读量:4321 次
发布时间:2019-06-06

本文共 1416 字,大约阅读时间需要 4 分钟。

要使n个农场从其他农场引水,或自己打井。

对于每个农场,最小花费为与min(自己打井,min(与其他农场连接));

当然,至少有一个农场打井。

这样选择后,得到了若干个联通块,每个块中有一个农场打井。

那么可以看出,每个农场需要直接或间接与水源相连。

把水源看作一个中转节点(虚根),每个农场与水源连边,边权即为修建水库的花费。

再将每对农场之间连边,所求即为这个图上的一个最小生成树。

这也符合至少有一个节点连接水源的要求。

 

代码不难,但是建立虚根的思路很重要。

代码如下

 

#include
#include
#include
#include
#define MogeKo qwq#include
using namespace std;const int maxn = 1e6;int n,x,cnt,ans,fa[maxn];struct node { int from,to,val; bool operator < (const node & N) const { return val < N.val; }} e[maxn];void add(int a,int b,int c) { e[++cnt].from = a; e[cnt].to = b; e[cnt].val = c;}int getfa(int x) { if(fa[x] == x)return x; else return fa[x] = getfa(fa[x]);}void kruskal(){ for(int i = 1;i <= cnt;i++){ int x = getfa(e[i].from); int y = getfa(e[i].to); if(x == y)continue; fa[x] = y; ans += e[i].val; }} int main(){ scanf("%d",&n); for(int i = 1;i <= n;i++) fa[i] = i; for(int i = 1;i <= n;i++){ scanf("%d",&x); add(0,i,x); } for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++){ scanf("%d",&x); if(j <= i)continue; add(i,j,x); } sort(e+1,e+cnt+1); kruskal(); printf("%d",ans); return 0;}
View Code

 

转载于:https://www.cnblogs.com/mogeko/p/10914111.html

你可能感兴趣的文章
Java中关键词之this,super的使用
查看>>
学习进度
查看>>
“此人不存在”
查看>>
github.com加速节点
查看>>
解密zend-PHP凤凰源码程序
查看>>
python3 序列分片记录
查看>>
Atitit.git的存储结构and 追踪
查看>>
atitit 读书与获取知识资料的attilax的总结.docx
查看>>
B站 React教程笔记day2(3)React-Redux
查看>>
找了一个api管理工具
查看>>
Part 2 - Fundamentals(4-10)
查看>>
使用Postmark测试后端存储性能
查看>>
NSTextView 文字链接的定制化
查看>>
第五天站立会议内容
查看>>
ATMEGA16 IOport相关汇总
查看>>
JAVA基础-多线程
查看>>
面试题5:字符串替换空格
查看>>
[Codevs] 线段树练习5
查看>>
Amazon
查看>>
component-based scene model
查看>>