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 ...
随机推荐
- java.String中的方法
(String) str.trim() 该方法返回一个复制该字符串的开头和结尾的白色空格去掉,或字符串,如果它没有头或尾空白. (Boolean) str.contains(str1) 判断 str ...
- stage3D基础三------什么是AGAL(转)
原文链接 http://www.adobe.com/cn/devnet/flashplayer/articles/hello-triangle.html 在本文中,你将研究一个能够正常运行的基于Sta ...
- vs2013中opencv的配置
下面开始介绍如何配置,我用的系统是win8.1 64位系统,vs用的是vs3013 ultimate,先到官网下载opencv 我用的的版本是最新的版本3.0 ALPHA,下载下来直接执行即可,实际上 ...
- iOS 10 中引入了 Message 框架
WWDC 2016 上最重磅的消息之一就是在 iOS 10 中引入了 Message 框架.开发者现在可以为苹果内置的 Messages 应用开发扩展啦.通过开发一个应用扩展,你可以让用户跟应用在 M ...
- php闭包简单实例
<?php function getClosure($i) { $i = $i.'-'.date('H:i:s'); return function ($param) use ($i) { ec ...
- thrift实例
Thrift实例 Apache thrift是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架. 它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生 ...
- WPF 支持集合绑定的控件
WPF 支持集合绑定的控件 ListBox ComboBox ListView DataGrid
- windowsphone8.1学习笔记之应用数据(四)
应用数据的存储格式常用的分为json和xml两种(其实我都想略过这个地方的,json我一直用的是json.net,而wp上操作xml的方式与其他相比也没太多变化). 先说说json数据存储,关于jso ...
- python解释器安装教程
1. 首先,打开python的官网:python.org 2. 首页downloads下打开, 3. 最上边是两个最新的版本,长期计划,推荐使用python3,如果长期打算用p3,默认使用最新版本.如 ...
- POJ 1518 A Round Peg in a Ground Hole【计算几何=_=你值得一虐】
链接: http://poj.org/problem?id=1584 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...