博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 1664 Conquer a New Region (Kruskal,贪心)
阅读量:5306 次
发布时间:2019-06-14

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

题意:在一颗树上要求一个到其他结点容量和最大的点,i,j之前的容量定义为i到j的路径上的最小边容量。

一开始想过由小到大的去分割边,但是很难实现,其实换个顺序就很容易做了,类似kruskal的一个贪心算法,

从大到小的连边,每次连通两个分量A和B,这样可以新边容量一定是两个分量相互到达的最小容量,其余边一定选最大,满足最优子结构

而且使新的连通分量取得最大值一定在其中一边,两者中选其中一者即可。具体实现用并查集维护即可。

 

#include
using namespace std;const int maxn = 2e5+5;typedef long long ll;struct node{ int cnt; ll sum;}town[maxn];int pa[maxn];int Find(int x) { return x==pa[x]?x:pa[x]=Find(pa[x]); }struct Edge{ int u,v,cap; bool operator < (const Edge &y) const { return cap > y.cap; }}road[maxn];#define initNode(x) pa[x] = x; town[x].cnt = 1; town[x].sum = 0;int main(){ //freopen("in.txt","r",stdin); int n; while(~scanf("%d",&n)){ for(int i = 1; i < n; i++){ scanf("%d%d%d",&road[i].u,&road[i].v,&road[i].cap); initNode(i); } initNode(n); sort(road+1,road+n); for(int i = 1; i < n; i++){ int x = Find(road[i].u), y = Find(road[i].v); ll t1 = town[x].sum + (ll)town[y].cnt*(ll)road[i].cap; ll t2 = town[y].sum + (ll)town[x].cnt*(ll)road[i].cap; if(t1>t2) swap(x,y),swap(t1,t2); pa[x] = y; town[y].sum = t2; town[y].cnt += town[x].cnt; } printf("%lld\n",town[Find(1)].sum); } return 0;}

 

转载于:https://www.cnblogs.com/jerryRey/p/4776461.html

你可能感兴趣的文章
Spring面试题
查看>>
窥视SP2010--第一章节--SP2010开发者路线图
查看>>
C语言栈的实现
查看>>
代码为什么需要重构
查看>>
TC SRM 593 DIV1 250
查看>>
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
Python-S9-Day127-Scrapy爬虫框架2
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
右侧导航栏(动态添加数据到list)
查看>>
81、iOS本地推送与远程推送详解
查看>>
虚拟DOM
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
关于View控件中的Context选择
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
Spark的启动进程详解
查看>>
使用命令创建数据库和表
查看>>
机器视觉:SSD Single Shot MultiBox Detector
查看>>
201521123044 《Java程序设计》第1周学习总结
查看>>
MIT Scheme 的基本使用
查看>>