博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1232: [Usaco2008Nov]安慰奶牛cheer(最小生成树)
阅读量:5056 次
发布时间:2019-06-12

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

题意:给一个图 需要找到一个子图使得所有点都连通

   然后再选择一个点做为起点 走到每个点并回到起点

   每条边,每个点被经过一次就要花费一次边权、点权

题解:肯定是找一颗最小生成树嘛

   然后惊奇的发现 任意选一个点做为一个起点遍历的答案都是 每条边走两次

   每个点度数是多少点权就统计几次 依题意起点多统计一次 那么起点就选一个点权最小的点

   然后把每条边两个端点的点权赋给它 跑一个最小生成树

   还是挺有意思的

 

#include 
using namespace std;int val[10005];int vis[10005];int pre[10005];struct node{ int u, v, w;}E[200005];bool cmp(node A, node B) {
return A.w < B.w;}int find(int x){ if(x == pre[x]) return x; else return pre[x] = find(pre[x]);}int main(){ int cnt = 0; int n, p; scanf("%d%d", &n, &p); for(int i = 1; i <= n; i++) pre[i] = i; int ans = 0; int tmp = 1005; for(int i = 1; i <= n; i++) scanf("%d", &val[i]), tmp = min(tmp, val[i]); ans += tmp; for(int i = 1; i <= p; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); E[++cnt].u = a; E[cnt].v = b; E[cnt].w = c * 2 + val[a] + val[b]; } sort(E + 1, E + 1 + cnt, cmp); int tot = 0; for(int i = 1; i <= cnt; i++) { if(tot == n - 1) break; int ax = find(E[i].u); int bx = find(E[i].v); if(ax == bx) continue; tot++; ans += E[i].w; pre[ax] = bx; } printf("%d\n", ans); return 0;}
View Code

 

转载于:https://www.cnblogs.com/lwqq3/p/9833071.html

你可能感兴趣的文章
Windows7中双击py文件运行程序
查看>>
Market entry case
查看>>
bzoj1230 开关灯 线段树
查看>>
LinearLayout
查看>>
学习python:day1
查看>>
css3动画属性
查看>>
第九次团队作业-测试报告与用户使用手册
查看>>
Equal Sides Of An Array
查看>>
CentOS笔记-用户和用户组管理
查看>>
Mongodb 基本命令
查看>>
Qt中QTableView中加入Check列实现
查看>>
“富豪相亲大会”究竟迷失了什么?
查看>>
控制文件的备份与恢复
查看>>
返回代码hdu 2054 A==B?
查看>>
Flink独立集群1
查看>>
iOS 8 地图
查看>>
20165235 第八周课下补做
查看>>
[leetcode] 1. Two Sum
查看>>
iOS 日常工作之常用宏定义大全
查看>>
PHP的SQL注入技术实现以及预防措施
查看>>