UVA 1664 Conquer a New Region (并查集+贪心)
并查集的一道比较考想法的题
题意:给你n个点,接着给你n-1条边形成一颗生成树,每条边都有一个权值。求的是以一个点作为特殊点,并求出从此点出发到其他每个点的条件边权的总和最大,条件边权就是:起点到终点经过的权值的最小值。
如果按照最原始的想法来做的话就是枚举每个点作为特殊点,离线dfs再遍历到每个点来计算条件边权总和,最后求一个最大值即可。但是此题点数有20万显然超时,接着想了一下是否可以枚举每个点后,使用数据结构或模拟dp(使用之前的条件边权总和)优化成为log2n,结果并没有什么想法。然而如果我不枚举点,直接贪心来做的话就可以解决问题了。我们可以想到每次加边的时候,权值必须小于那些(出现过的任意一对点),才会影响那些的权值,因此可以想到排序权值。
我的想法是这样的:我们离线操作从大到小排序权值,使用并查集把祖先节点看做特殊点,接着每次加边的时候更新祖先(合并操作),更新时需要决定祖先是哪个。我们知道更新后的祖先是要保证树上的每个点到其的条件边权的总和最大,而两棵树的祖先之一才可能出现这种情况(满足后效性),所以我们只需要需要比较两个祖先。此时我们可以想到,如果A树的祖先为更新后的祖先,A树上的条件边权总和并不会变,而B树上的每个点的条件边权则会变成现在加边的权值(我们从大到小排的序),所以我们只需再祖先上的记录两个权值:一个是树上总点数num,一个此树条件边权的总和manx。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
int fat[Max],num[Max];
ll manx[Max];
struct node
{
int xx1,yy1,val;
}tow[Max];
void Init(int n)
{
for(int i=;i<=n;i++)
{
fat[i]=i;
num[i]=;
manx[i]=0ll;
}
return;
}
bool cmp(struct node p1,struct node p2)
{
return p1.val>p2.val;
}
int Find(int x)
{
if(x==fat[x])
return fat[x];
return fat[x]=Find(fat[x]);
}
void Union(int x,int y,int z)
{
int x1=Find(x);
int y1=Find(y);
if((ll)num[x1]*z+manx[y1]>(ll)num[y1]*z+manx[x1])//哪边为根权值和最大
{
fat[x1]=y1;
manx[y1]+=(ll)num[x1]*z;
num[y1]+=num[x1];
}
else
{
fat[y1]=x1;
manx[x1]+=(ll)num[y1]*z;
num[x1]+=num[y1];
}
return;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
Init(n);
for(int i=;i<n-;i++)
scanf("%d %d %d",&tow[i].xx1,&tow[i].yy1,&tow[i].val);
sort(tow,tow+n-,cmp);//点与点之间的权值为所形成路径的最小权值,最大的权值最先找祖先保证合并时最小权值一定是当前权值
for(int i=;i<n-;i++)
Union(tow[i].xx1,tow[i].yy1,tow[i].val);
printf("%lld\n",manx[Find()]);//形成一棵树,答案在根节点
}
return ;
}
UVA 1664 Conquer a New Region (并查集+贪心)的更多相关文章
- UVA 1664 Conquer a New Region (Kruskal,贪心)
题意:在一颗树上要求一个到其他结点容量和最大的点,i,j之前的容量定义为i到j的路径上的最小边容量. 一开始想过由小到大的去分割边,但是很难实现,其实换个顺序就很容易做了,类似kruskal的一个贪心 ...
- hdu 4424 & zoj 3659 Conquer a New Region (并查集 + 贪心)
Conquer a New Region Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- UVa 1664 Conquer a New Region(并查集)
https://vjudge.net/problem/UVA-1664 题意: n个城市形成一棵树,每条边有权值C(i,j).任意两个点的容量S(i,j)定义为i与j唯一通路上容量的最小值.找一个点, ...
- ZOJ3659 Conquer a New Region 并查集
Conquer a New Region Time Limit: 5 Seconds Memory Limit: 32768 KB The wheel of the history roll ...
- hdu4424 Conquer a New Region 并查集/类似最小生成树
The wheel of the history rolling forward, our king conquered a new region in a distant continent.The ...
- ZOJ 3659 & HDU 4424 Conquer a New Region (并查集)
这题要用到一点贪心的思想,因为一个点到另一个点的运载能力决定于其间的边的最小权值,所以先把线段按权值从大到小排个序,每次加的边都比以前小,然后合并集合时,比较 x = findset(a) 做根或 y ...
- zoj 3659 Conquer a New Region(并查集)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4882 代码: #include<cstdio> #inc ...
- hdu 4424 Conquer a New Region (并查集)
///题意:给出一棵树.树的边上都有边权值,求从一点出发的权值和最大,权值为从一点出去路径上边权的最小值 # include <stdio.h> # include <algorit ...
- HDU 1598 find the most comfortable road 并查集+贪心
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1598 find the most comfortable road Time Limit: 1000 ...
随机推荐
- [Hibernate开发之路](4)ID生成策略
一 对象关系数据库映射之Id 被映射的类必须定义相应数据库表主键字段.大多数类有一个JavaBeans风格的属性, 为每个实例包括唯一的标识. <id> 元素定义了该属性到数据库表主键字段 ...
- win10--vs2015--libjpeg--64位库的编译过程记录
win10--vs2015--libjpeg--64位库的编译过程记录 1. 下载源代码: http://libjpeg.sourceforge.net/ 或者 http://www.ij ...
- codeforces 427 div.2 F. Roads in the Kingdom
F. Roads in the Kingdom time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- log4j日志异步化大幅提升系统性能
.log4j已成为大型系统必不可少的一部分,log4j可以很方便的帮助我们在程序的任何位置输出所要打印的信息,便于我们对系统在调试阶段和正式运行阶段对问题分析和定位.由于日志级别的不同,对系统的性能影 ...
- vue prop不同数据类型(数组,对象..)设置默认值
vue prop 会接收不同的数据类型,这里列出了 常用的数据类型的设置默认值的写法,其中包含: Number, String, Boolean, Array, Function, Object ...
- pycharm的安装和破解
前提: 为了学习爬虫,单独下载了一个pycharm编辑器,所以就有了这篇文章,和PHPstorm的安装和破解及其类似, 如有想了解PHPstorm的安装破解可参考我的另一篇博文:http://www. ...
- css 坑记
1. div 内容超出 (做换行处理) 要注意 white-space属性的运用 设置 div width:100%;(或者固定值) 设置换行 word-break: break-all; 设置 ...
- plsql 详细安装及汉化步骤
方法/步骤 双击运行plsqldev715 安装完成后我们装中文补丁: 双击运行‘Chinese’应用程序 找到PLSQL的安装目录添加进来 中文补丁安装完成后我们需要进行orcl的配置,配置好才 ...
- amoeba安装与简单使用(一)
1.我的环境Amoeba 2.0.1 -- CentOS release 6.8 (Final) -- 10.20.49.254Mysql 5.1.73 -- CentOS release 6.4 ( ...
- ubuntu 17 编译BTCoin
一. 安装开发环境 sudo apt-get update sudo apt-get install build-essential libtool autotools-dev autoconf pk ...