Codeforces F. Imbalance Value of a Tree(并查集加排序,树)

2024-04-15 22:48

本文主要是介绍Codeforces F. Imbalance Value of a Tree(并查集加排序,树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意:
求出树中所有路径最大值减去最小值之和

思路:
美团笔试遇到了这题,这里再学习一下。

首先考虑简单版本,求出所有路径最大值之和。可以先将所有点按照值排序,然后依次取,每次只考虑所有取出的点,当前的点就是所有点中的最大值点。通过并查集统计点的数目再计数。最小值和也是一样的,将值取负就可以了。

具体统计的细节可以看代码,挺好懂的,一个计数问题。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <set>
using namespace std;
typedef long long ll;const int maxn = 1e6 + 7;
struct Node {int id, w;
}a[maxn];
int head[maxn], nex[maxn * 2], to[maxn * 2], tot;
int fa[maxn], num[maxn], vis[maxn], n;
ll ans;
int cmp(Node a, Node b) {return a.w < b.w;
}
int findset(int i) {if(i == fa[i]) return i;return fa[i] = findset(fa[i]);
}
void add(int x,int y) {to[++tot] = y;nex[tot] = head[x];head[x] = tot;
}
void init() {sort(a, a + n, cmp);for(int i = 0;i < n;i++) {fa[i] = i;num[i] = 1;vis[i] = 0;}
}
void solve() {init();for(int i = 0;i < n;i++) {for(int j = head[a[i].id]; j; j = nex[j]) {int v = to[j];int now = findset(v);if(!vis[now]) {continue;}ans += 1ll * a[i].w * num[now] * num[a[i].id];num[a[i].id] += num[now];fa[now] = a[i].id;}a[i].w = -a[i].w;vis[a[i].id] = 1;}
}
int main() {scanf("%d",&n);for(int i = 0;i < n;i++) {scanf("%d",&a[i].w);a[i].id = i;}for(int i = 0;i < n - 1;i++) {int x, y;scanf("%d%d", &x, &y);x--;y--;add(x, y); add(y, x);}solve();solve();printf("%lld\n", ans);return 0;
}

这篇关于Codeforces F. Imbalance Value of a Tree(并查集加排序,树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907146

相关文章

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

【软考】希尔排序算法分析

目录 1. c代码2. 运行截图3. 运行解析 1. c代码 #include <stdio.h>#include <stdlib.h> void shellSort(int data[], int n){// 划分的数组,例如8个数则为[4, 2, 1]int *delta;int k;// i控制delta的轮次int i;// 临时变量,换值int temp;in