并查集的一道比较考想法的题 
题意:给你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 (并查集+贪心)的更多相关文章

  1. UVA 1664 Conquer a New Region (Kruskal,贪心)

    题意:在一颗树上要求一个到其他结点容量和最大的点,i,j之前的容量定义为i到j的路径上的最小边容量. 一开始想过由小到大的去分割边,但是很难实现,其实换个顺序就很容易做了,类似kruskal的一个贪心 ...

  2. 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 ...

  3. UVa 1664 Conquer a New Region(并查集)

    https://vjudge.net/problem/UVA-1664 题意: n个城市形成一棵树,每条边有权值C(i,j).任意两个点的容量S(i,j)定义为i与j唯一通路上容量的最小值.找一个点, ...

  4. ZOJ3659 Conquer a New Region 并查集

    Conquer a New Region Time Limit: 5 Seconds      Memory Limit: 32768 KB The wheel of the history roll ...

  5. hdu4424 Conquer a New Region 并查集/类似最小生成树

    The wheel of the history rolling forward, our king conquered a new region in a distant continent.The ...

  6. ZOJ 3659 & HDU 4424 Conquer a New Region (并查集)

    这题要用到一点贪心的思想,因为一个点到另一个点的运载能力决定于其间的边的最小权值,所以先把线段按权值从大到小排个序,每次加的边都比以前小,然后合并集合时,比较 x = findset(a) 做根或 y ...

  7. zoj 3659 Conquer a New Region(并查集)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4882 代码: #include<cstdio> #inc ...

  8. hdu 4424 Conquer a New Region (并查集)

    ///题意:给出一棵树.树的边上都有边权值,求从一点出发的权值和最大,权值为从一点出去路径上边权的最小值 # include <stdio.h> # include <algorit ...

  9. HDU 1598 find the most comfortable road 并查集+贪心

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1598 find the most comfortable road Time Limit: 1000 ...

随机推荐

  1. Java 多线程 并发编程 (转)

    一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种 ...

  2. linux系统下实时监控进程以及定位杀死挂起的进程

    一.实时监测进程 [root@instance-3lm099to ~]# top top - :: up days, min, users, load average: 0.01, 0.05, 0.0 ...

  3. MySQL三:存储引擎

    阅读目录 一 什么是存储引擎 二 mysql支持的存储引擎 三 使用存储引擎 一 什么是存储引擎 mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的 ...

  4. Thread 常搞混的几个概念sleep、wait、yield、interrupt

    sleep:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响.该线程不丢失任何监视器的所属权. 通过调用sleep使任务进入休眠状态,在这种情况下 ...

  5. lua学习笔记(十二)

    弱引用table     lua使用自动内存管理机制,通过垃圾回收器来回收内存     垃圾回收器只能回收它认为是垃圾的内容,而不能回收用户认为是垃圾的内容     典型的例子栈,栈一般用一个数组和一 ...

  6. [译]NeHe教程 - 添加颜色

    原文: Adding Colour 上一节我讲解了如何在屏幕显示三角形和四边形.本节会讲解如何上色.单色(Flat)顾名思义就是只能涂一种实心的颜色.平滑颜色(Smooth)可以在各个顶点混合三种颜色 ...

  7. 《TomCat与Java Web开发技术详解》(第二版) 第三章节的学习总结--利用Context元素来自定义web应用的存储位置

    在学习完第三章后(第三章提供的web应用是helloaapp,我将其放到了tomcat/webapps中),对Context元素的作用理解不深:但是当进入第四章后,发现第四章提供的源码包中也有一个叫h ...

  8. 为什么是kafka(二)

    回答几个网友提出的问题,不清楚的能够看上一篇内容. 1.  kafka的删除策略应该怎么配置?为了提升性能.我是不是应该1小时删除一次消费过的数据. 全然能够依据磁盘大小配置.仅仅要磁盘足够用,全然不 ...

  9. hdu3579(线性同余方程组)

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. 【基础版限时免费】致敬WebForms,ASP.NET Core也能这么玩!

    ASP.NET WebForms ASP.NET WebForms 随着微软 2000 年的 .Net Framework 一起发布,至今也将近 20 年的时间.相信很多人和我一样,对 WebForm ...