[并查集+LCA USACO18OPEN ] Disruption
https://www.luogu.org/problemnew/show/P4374
一看这道题就是一个妙题,然后题解什么树链剖分...珂朵莉树...
还不如并查集来的实在!我们知道并查集本来就是路径压缩的。
比如这题可以树上的路径压缩!! 直接跳到father,就省去大量上跳的过程(因为我们已经计算过了,不存在最优了)。
下面给出题面:
给出n个节点的树,现在有m条边可供替换,对于树上每一条边删除,
为了保证整颗树强连通,需要从给出的边中选出一条添加上,
求对于删除的每一条树边,最小添加上的给出的边的长度。
对于100%的数据 $n \leq 5\times 10^4 $
做法的话就是首先建这棵树然后把每一条边记录它的编号i然后LCA预处理都会的吧
按照边权排序然后枚举这条边可以完成哪些边删除后的替代作用,显然的一个贪心,前面枚举的边权小如果被小边权选过了
那么后面的边即使可以选上也一定比前面的边权大,所以只要可行,我们就使用并查集把这条边直接折叠掉,下次不做遍历。
对于每一条边的答案存在它的末端,可以比较方便处理。暴力找不断按照father跳到lca及以上就行。
code :
# include <cstdio>
# include <algorithm>
using namespace std;
const int N=5e4+;
struct rec{ int u,v,w; }e[N];
struct Edg{ int pre,to,id; }a[N<<];
int n,m,tot;
int dep[N],g[N][],f[N],head[N],arc[N],ans[N];
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
void swap(int &x,int &y){int t=x;x=y;y=t;}
void write(int x)
{
if (x==-) { putchar('-'); putchar(''); return;}
if (x>) write(x/);
putchar(x%+'');
}
void adde(int id,int u,int v)
{
a[++tot].pre=head[u];
a[tot].to=v;
a[tot].id=id;
head[u]=tot;
}
int father(int x)
{
if (f[x]==x) return x;
return f[x]=father(f[x]);
}
bool cmp(rec aa,rec bb){return aa.w<bb.w;}
void dfs(int u,int fath)
{
g[u][]=fath; dep[u]=dep[fath]+;
for (int i=head[u];i;i=a[i].pre) {
int v=a[i].to; if (v==fath) continue;
arc[a[i].id]=v;
dfs(v,u);
}
}
void init()
{
for (int j=;j<=;j++)
for (int i=;i<=n;i++)
g[i][j]=g[g[i][j-]][j-];
}
int lca(int u,int v)
{
if (dep[u]<dep[v]) swap(u,v);
for (int i=;i>=;i--)
if (dep[g[u][i]]>=dep[v]) u=g[u][i];
if (u==v) return u;
for (int i=;i>=;i--)
if (g[u][i]!=g[v][i]) u=g[u][i],v=g[v][i];
return g[u][];
}
int main()
{
n=read();m=read();
int u,v;
for (int i=;i<n;i++) {
u=read();v=read();
adde(i,u,v); adde(i,v,u);
}
dfs(,); init();
for (int i=;i<=m;i++)
e[i]=(rec){read(),read(),read()};
sort(e+,e++m,cmp);
for (int i=;i<=n;i++) f[i]=i,ans[i]=-;
for (int i=;i<=m;i++) {
int w=e[i].w,u=e[i].u,v=e[i].v,Lca=lca(u,v);
for (u=father(u);dep[u]>dep[Lca];u=father(g[u][]))
ans[u]=w,f[u]=g[u][];
for (v=father(v);dep[v]>dep[Lca];v=father(g[v][]))
ans[v]=w,f[v]=g[v][];
}
for (int i=;i<n;i++) write(ans[arc[i]]),putchar('\n');
return ;
}
[并查集+LCA USACO18OPEN ] Disruption的更多相关文章
- hdu 2874 Connections between cities (并查集+LCA)
Connections between cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- hdu6074[并查集+LCA+思维] 2017多校4
看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...
- Gym 100814C Connecting Graph 并查集+LCA
Description standard input/output Statements Alex is known to be very clever, but Walter does not be ...
- Network-POJ3694并查集+LCA
Network Time Limit: 5000MS Memory Limit: 65536K Description A network administrator manages ...
- Mobile Phone Network CodeForces - 1023F(并查集lca+修改环)
题意: 就是有几个点,你掌控了几条路,你的商业对手也掌控了几条路,然后你想让游客都把你的所有路都走完,那么你就有钱了,但你又想挣的钱最多,真是的过分..哈哈 游客肯定要对比一下你的对手的路 看看那个便 ...
- HDU6074 Phone Call (并查集 LCA)
Phone Call Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Tota ...
- 习题:过路费(kruskal+并查集+LCA)
过路费 [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费 ...
- BZOJ 4668 冷战(按秩合并并查集+LCA)
4668: 冷战 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 627 Solved: 303[Submit][Status][Discuss] D ...
- [CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)
题目描述 比特山是比特镇的飙车圣地.在比特山上一共有$n$个广场,编号依次为$1$到$n$,这些广场之间通过$n−1$条双向车道直接或间接地连接在一起,形成了一棵树的结构. 因为每条车道的修建时间以及 ...
随机推荐
- 利用数据库触发器让字段与自增长Id相关联
十年河东,十年河西,莫欺少年穷 学无止境,精益求精 今天是数据库脚本类的代码,所以不想过多阐述 如下数据表: create table Card( Id ,) primary key, CardNo ...
- 浅谈博弈论中的两个基本模型——Bash Game&&Nim Game
最近在数学这一块搞了蛮多题目,已经解决了数论基础,线性代数(只有矩阵,行列式待坑),组合数学中的一些简单问题.所以接下来不可避免的对博弈论这一哲学大坑开工. 当然,由于我很菜,所以也只能从最基础最容易 ...
- Libgdx学习记录28——创建Desktop程序
1.新建Java Project. 2.添加libs,添加相关的jar文件. 3. 在Project Build Path中,添加Reference. 4. 添加文件夹assets,并右键Build ...
- Socket异步通信及心跳包同时响应逻辑分析(最后附Demo)。
有段时间没有更博了,刚好最近在做Socket通信的项目,原理大致内容:[二维码-(加logo)]-->提供主机地址和端口号信息(直接使用[ThoughtWorks.QRCode.dll]比较简单 ...
- C#_Math函数总结
Math.abs() 计算绝对值. Math.acos() 计算反余弦值. Math.asin() 计算反正弦值. Math.atan() 计算反正切值. Math.atan2() 计算从x 坐标轴到 ...
- CrackMe005-下篇 | 逆向破解分析 | 160个CrackMe(视频+图文)深度解析系列
作者:逆向驿站微信公众号:逆向驿站知乎:逆向驿站 CrackMe005,上篇说了具体方法,下篇来发逆向分析过程,看看老夫是如何得到上篇的具体方法的! 准备 [环境和工具] win7/xp虚拟机环境 C ...
- libmysqlclient.so.16: cannot open shared object file: No such file or directory
编译安装的mysql5.6.39,安装目录是/usr/local/mysql,启用程序时报错:libmysqlclient.so.16: cannot open shared object file: ...
- git-两小时简单使用教程
两小时学会Git玩转Github 1. 了解Git和Github 1.1什么是Git Git是一个免费.开源的版本控制软件 1.2什么是版本控制系统 版本控制是一种记录一个或若干个文件内容变化,以便将 ...
- PairWork-电梯调度程序结对编程
结对编程人员:050/184 1 结对编程 1.1 结对编程的优缺点 优点: ● 与单独开发相比,结对能够使人们在压力之下保持更好的状态.结对编程鼓励双方保持代码的高质量,即使在出现了让人不得不飞快地 ...
- 《移山之道》Reading Task
老师布置的阅读任务虽然是附加的作业,但是对我来说是个很好的学习机会.软件工程主要是对工程的开发进行学习,毕竟在学校老师教了那么多的知识,我们课下做了那么多的练习并没有提高我们做一个工程的能力.一个项目 ...