D. Best Edge Weight(最小生成树 + 树链剖分)(Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals))

D. Best Edge Weight

给定一个有nnn个点mmm条边的无向连通图,有mmm次询问,每次询问第iii条边的权值最大为多少,这张图的所有最小生成树的方案中,一定包含第iii条边。

先跑一边最小生成树,得到最小生成树,然后依次统计答案,分两种情况:

1、这条边在最小生成树上

假设这条边的边权为valuevaluevalue,把这条边断开,则分成了两个集合A,BA, BA,B,那么有一个性质,从集合AAA连向集合BBB的边,边权一定大于等于valuevaluevalue

如果从集合AAA连向集合BBB的边只有一条,则这条边必定存在,答案为−1-11

如果从集合AAA连向集合BBB的边,边权为valuevaluevalue的只有一条,则答案为除这条边以外的最小边权 - 1。

否则的话,答案就是value−1value - 1value1了 。

2、这条边不在最小生成树上

考虑找到u−>vu->vu>v路径上权值最大的边valuevaluevalue,把这条边断开,分成了两个集合A,BA, BA,B,同样的有一个性质,从集合AAA连向集合BBB的边,边权一定大于等于valuevaluevalue

所以要使A,BA,BA,B集合联通,且这条边一定出现,则边权为value−1value - 1value1即可。

对第 2 种情况,可以考虑树链剖分,然后线段树维护区间最大值即可,单次询问复杂度log⁡nlog⁡n\log n \log nlognlogn,考虑如何解决第一种情况。

对第 1 种情况,用线段树维护一个区间最小值跟区间最小值个数,然后单点查询最小值个数即可,边权下放成点权,树链剖分。

#include <bits/stdc++.h>
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;const int N = 2e5 + 10;int head[N], to[N << 1], nex[N << 1], value[N << 1], cnt = 1;int son[N], sz[N], dep[N], fa[N], rk[N], id[N], top[N], tot;int ff[N], vis[N], w[N], ans[N], n, m;struct Res {int u, v, w, id;bool operator < (const Res &t) const {return w < t.w;}
}edge[N];void add(int x, int y, int w) {to[cnt] = y;nex[cnt] = head[x];value[cnt] = w;head[x] = cnt++;
}int find(int rt) {return ff[rt] == rt ? rt : ff[rt] = find(ff[rt]);
}void dfs1(int rt, int f) {fa[rt] = f, dep[rt] = dep[f] + 1, sz[rt] = 1;for (int i = head[rt]; i; i = nex[i]) {if (to[i] == f) {continue;}w[to[i]] = value[i];dfs1(to[i], rt);sz[rt] += sz[to[i]];if (!son[rt] || sz[to[i]] > sz[son[rt]]) {son[rt] = to[i];}}
}void dfs2(int rt, int tp) {rk[++tot] = rt, id[rt] = tot, top[rt] = tp;if (!son[rt]) {return ;}dfs2(son[rt], tp);for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa[rt] || to[i] == son[rt]) {continue;}dfs2(to[i], to[i]);}
}void Kruskal() {sort(edge + 1, edge + m + 1);for (int i = 1; i <= n; i++) {ff[i] = i;}for (int i = 1, sum = 0; i <= m && sum < n; i++) {int u = find(edge[i].u), v = find(edge[i].v);if (u == v) {continue;}ff[u] = v, vis[i] = 1, sum++;add(edge[i].u, edge[i].v, edge[i].w);add(edge[i].v, edge[i].u, edge[i].w);}dfs1(1, 0);dfs2(1, 1);
}int maxn[N << 2], minn[N << 2], lazy[N << 2];void push_up(int rt) {maxn[rt] = max(maxn[ls], maxn[rs]);
}void push_down(int rt) {if (lazy[rt] != 0x3f3f3f3f) {minn[ls] = min(minn[ls], lazy[rt]), minn[rs] = min(minn[rs], lazy[rt]);lazy[ls] = min(lazy[ls], lazy[rt]), lazy[rs] = min(lazy[rs], lazy[rt]);lazy[rt] = 0x3f3f3f3f;}
}void build(int rt, int l, int r) {minn[rt] = lazy[rt] = 0x3f3f3f3f;if (l == r) {maxn[rt] = w[rk[l]];return ;}build(lson);build(rson);push_up(rt);
}void update(int rt, int l, int r, int L, int R, int v) {if (l >= L && r <= R) {lazy[rt] = min(lazy[rt], v);minn[rt] = min(minn[rt], v);return ;}push_down(rt);if (L <= mid) {update(lson, L, R, v);}if (R > mid) {update(rson, L, R, v);}
}int query_max(int rt, int l, int r, int L, int R) {if (l >= L && r <= R) {return maxn[rt];}push_down(rt);int maxn = 0;if (L <= mid) {maxn = max(maxn, query_max(lson, L, R));}if (R > mid) {maxn = max(maxn, query_max(rson, L, R));}return maxn;
}int query_min(int rt, int l, int r, int x) {if (l == r) {return minn[rt];}push_down(rt);if (x <= mid) {return query_min(lson, x);}else {return query_min(rson, x);}
}void update(int u, int v, int w) {while (top[u] != top[v]) {if (dep[top[u]] < dep[top[v]]) {swap(u, v);}update(1, 1, n, id[top[u]], id[u], w);u = fa[top[u]];}if (u != v) {if (dep[u] > dep[v]) {swap(u, v);}update(1, 1, n, id[u] + 1, id[v], w);}
}int query(int u, int v) {int maxn = 0;while (top[u] != top[v]) {if (dep[top[u]] < dep[top[v]]) {swap(u, v);}maxn = max(maxn, query_max(1, 1, n, id[top[u]], id[u]));u = fa[top[u]];}if (u != v) {if (dep[u] > dep[v]) {swap(u, v);}maxn = max(maxn, query_max(1, 1, n, id[u] + 1, id[v]));}return maxn;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d %d", &n, &m);for (int i = 1, u, v, w; i <= m; i++) {scanf("%d %d %d", &u, &v, &w);edge[i] = {u, v, w, i};}Kruskal();build(1, 1, n);for (int i = 1; i <= m; i++) {if (!vis[i]) {update(edge[i].u, edge[i].v, edge[i].w);}}for (int i = 1; i <= m; i++) {if (vis[i]) {int u = edge[i].u, v = edge[i].v;if (dep[u] < dep[v]) {swap(u, v);}int cur = query_min(1, 1, n, id[u]);if (cur == edge[i].w) {ans[edge[i].id] = edge[i].w - 1;}else if (cur == 0x3f3f3f3f) {ans[edge[i].id] = -1;}else {ans[edge[i].id] = cur - 1;}}else {ans[edge[i].id] = query(edge[i].u, edge[i].v) - 1;}}for (int i = 1; i <= m; i++) {printf("%d%c", ans[i], i == m ? '\n' : ' ');}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313739.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用Helm简化Kubernetes应用部署(1)

目录利用Helm简化Kubernetes应用部署 Helm基础 安装Helm 使用Visual Studio 2019为Helm编写一个简单的应用 利用Helm简化Kubernetes应用部署Helm是Kubernetes生态系统中的一个软件包管理工具&#xff0c;有点类似于Linux操作系统里面的“apt-get”和“yum”。结合上一节内容&am…

设计模式——行为型模式

一&#xff1a;目录 1. 策略模式&#xff08;Strategy&#xff09; 2.状态模式&#xff08;State&#xff09; 3.责任链模式&#xff08;Chain Of Responsibility&#xff09; 4.解释器模式&#xff08;Interpreter&#xff09; 5.命令模式&#xff08;Command&#xff09; 6.观…

2019 ICPC Asia Yinchuan Regional(9 / 13)

2019 ICPC Asia Yinchuan Regional A - Girls Band Party&#xff08;分组背包&#xff09; 每个物品有两个标签&#xff0c;名字&#xff0c;颜色&#xff0c;当名字是设置为奖赏时会对整体加上0.1 的贡献&#xff0c;如果颜色符合要求时 会对整体加上 0.2 的的贡献 但是有…

网络编程——常用协议解析

** 1、网络基础知识 ** 1.1> 什么是OSI模型 OSI 模型(Open System Interconnection model)是一个由国际标准化组织?提出的概念模型,试图?供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每层都可以提供抽象良好的…

在 ABP vNext 中编写仓储单元测试的问题一则

一、问题新项目是基于 ABP vNext 框架进行开发的&#xff0c;所以我要求为每层编写单元测试。在同事为某个仓储编写单元测试的时候&#xff0c;发现了一个奇怪的问题。他的对某个聚合根的 A 字段进行了更新&#xff0c;随后对某个导航属性 B 也进行了变更&#xff0c;最后通过仓…

TCP协议——三次握手与四次关闭

1. TCP协议基础 网络编程基础见&#xff0c;传送门 TCP是面向连接的&#xff0c;无论哪一方向另一方发送数据之前&#xff0c;都必须先在双方之间建立一条连接。 在TCP/IP协议中&#xff0c;TCP协议提供可靠的连接服务&#xff0c;连接是通过三次握手进行初始化的。 三次握手…

在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想

源码&#xff1a;https://github.com/Martin1994/JsonJitSerializerNuGet&#xff1a;https://www.nuget.org/packages/MartinCl2.Text.Json.Serialization/简介&#xff1a;Just-in-time 编译的 JSON 序列化&#xff0c;基于 System.Text.Json.NET Core 3.0 即将正式发布&…

E. Company(Codeforces Round #520 (Div. 2))

E. Company 给定一颗有nnn个节点的树&#xff0c;有mmm次询问&#xff0c;每次询问给定[l,r][l, r][l,r]&#xff0c;我们可以选择删除其中的一个点ppp&#xff0c;然后找到一个深度最深的rtrtrt&#xff0c;使得剩下的点都在rtrtrt的子树上。 考虑对编号为[l,r][l, r][l,r]中…

TCP协议——流量控制和拥塞控制

** 一、流量控制 ** 1.1 什么是流量控制 Sender won’t overflow receiver’s buffer by transmitting too much, too fast. &#xff08;防止发送方发的太快&#xff0c;耗尽接收方的资源&#xff0c;从而使接收方来不及处理&#xff09; 1.2 流量控制的一些知识点 &#x…

征集.NET中国峰会议题

月初做的调查《》&#xff0c;参与人数576人&#xff0c;愿意参与分享.NET Core经验的142人&#xff0c;今天发起分会场主题演讲和闪电演讲议题.2014年微软组织成立.NET基金会&#xff0c;微软在成为主要的开源参与者的道路上又前进了一步。2014年以来已经有众多知名公司加入.N…

TCP协议——粘包与拆包

TCP的基础 TCP协议基础&#xff0c;传送门 TCP协议流量控制&#xff0c;传送门 1.1 什么是TCP粘包/拆包 TCP是个“流”协议&#xff0c;所谓流&#xff0c;就是没有界限的一串数据。大家可以想想河里的流水&#xff0c;是连成一片的&#xff0c;其间并没有分界线。TCP底层并…

B. Lynyrd Skynyrd(倍增 + 区间最小值)

B. Lynyrd Skynyrd&#xff08;segment tree redouble&#xff09; 给定一个长度为nnn的排列ppp&#xff0c;一个长度为mmm的数组aaa&#xff0c;有mmm次询问&#xff0c;每次询问给定l,rl, rl,r&#xff0c;问在数组aaa中是否存在一个子序列构成的串是ppp的循环位移串&#…

你的通勤时间都去哪了?

大家好&#xff0c;我是Z哥。今天我来唠叨一下。最近无意间看到一份报告&#xff0c;关于我们职场人士上下班通勤时间的。有时候想想也挺无奈的&#xff0c;我们越想去发达一些的城市打拼&#xff0c;反而越被通勤这种琐碎的事情给耽误更多的奋斗时间。但是没办法&#xff0c;在…

规模化敏捷必须SAFe

引子&#xff1a;规模化敏捷转型从来不是一件容易的事情。当只有1-2个敏捷团队进行协同的时候&#xff0c;计划和工作同步是可控的。团队和产品负责人互相聊一聊&#xff0c;基本就能搞清楚需要做什么&#xff0c;一个简单的SOS架构&#xff08;Scrum of Scrums&#xff09;就能…

http1.0 http1.1 http2 之间的区别

一、HTTP基础 1.1 HTTP定义 HTTP协议&#xff08;HyperTextTransferProtocol&#xff0c;超文本传输协议&#xff09;是用于从WWW服务器传输超文本到本地浏览器的传输协议。 1.2 HTTP发展史 1.3 HTTP1.0 早先1.0的HTTP版本&#xff0c;是一种无状态、无连接的应用层协议。 …

B. Alyona and a tree(dsu on tree + bit)

B. Alyona and a tree&#xff08;dsu on tree bit&#xff09; 给定一颗以111号节点为根的树&#xff0c;每个点有点权aia_iai​&#xff0c;边有边权&#xff0c;如果vvv控制了点uuu&#xff0c;当且仅当uuu是vvv的子树中的节点且dis(u,v)≤audis(u, v) \leq a_udis(u,v)≤…

HTTP get post put delte等

超文本传输协议&#xff08;HTTP, HyperText Transfer Protocol&#xff09;是一种无状态的协议&#xff0c;它位于OSI七层模型的传输层。HTTP客户端会根据需要构建合适的HTTP请求方法&#xff0c;而HTTP服务器会根据不同的HTTP请求方法做出不同的响应。 HTTP版本与HTTP请求方…

P1600 [NOIP2016 提高组] 天天爱跑步(线段树合并,lca)

P1600 [NOIP2016 提高组] 天天爱跑步 给定一颗有nnn个点的树&#xff0c;有mmm个人在树上移动&#xff0c;第iii个人从sis_isi​点&#xff0c;移动到tit_iti​点&#xff0c;且他们按照最短路移动&#xff0c;每秒移动一条边的距离&#xff0c; 点iii在wiw_iwi​时刻有一个观…

漫画:程序员一时单身一时爽,一直单身...有点惨

1妹子没吃早饭早啊敲哥&#xff0c;你在吃早饭啊嗯啊&#xff0c;你吃了吗&#xff1f;没呢&#xff0c;早上实在是太赶了&#xff0c;没来得及嗯...那我还是换个地方吃吧免得馋着你。。。2代码重要还是女朋友重要女朋友能哄好&#xff0c;代码能哄好吗&#xff1f;写代码是赚钱…

P3564 [POI2014]BAR-Salad Bar(ST表 + 二分)

P3564 [POI2014]BAR-Salad Bar 给定一个长度为nnn的数组&#xff0c;里面元素只有111跟−1-1−1&#xff0c;问选出一个长度为lenlenlen的区间使得&#xff0c;这个区间的前缀和时刻大于零&#xff0c;后缀和时刻大于零&#xff0c;输出最大长度lenlenlen&#xff0c; 考虑枚…