【LCA+MST】BZOJ3732-Network
【题目大意】
给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。图中有M条边 (1<=M<=30,000) ,第j条边的长度:d_j (1<=d_j <=1,000,000,000)。现在有 K个询问 (1 < = K < = 15,000), 每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?
【思路】
显然,最小的最长边应该在MST上。先跑出MST,然后对于每个询问跑LCA,在跑LCA的过程中顺便处理最长边。
LCA处理最长边是第一次写,但是这种东西,yy一下就好了,和LCA里面的祖先数组长得是一样的啊……
【错误点】
LCA是最后a的父亲,所以我们还要比较一下a和它父亲的连边……
#include<bits/stdc++.h>
using namespace std;
const int MAXN=+;
const int MAXM=+;
const int DEG=;
struct Edge
{
int u,v,w;
bool operator < (const Edge &x) const
{
return w<x.w;
};
};
Edge edge[MAXM];
vector<Edge> E[MAXN];
int n,m,k;
int u[MAXN],h[MAXN];
int dep[MAXN],anc[MAXN][DEG],maxlen[MAXN][DEG]; void addedge(int u,int v,int w)
{
E[u].push_back((Edge){u,v,w});
E[v].push_back((Edge){v,u,w});
} int find(int x)
{
int r=x;
while (u[r]!=r) r=u[r];
int tmp;
while (u[x]!=x)
{
tmp=u[x];
u[x]=r;
x=tmp;
}
return r;
} void union_set(int fa,int fb)
{
if (h[fa]>=h[fb])
{
u[fb]=fa;
if (h[fa]==h[fb]) h[fa]++;
}
else u[fa]=fb;
} void dfs(int u,int fa,int d)
{
anc[u][]=fa;
dep[u]=d;
for (int i=;i<E[u].size();i++)
{
int to=E[u][i].v;
if (to==fa) continue;
maxlen[to][]=E[u][i].w;
dfs(to,u,d+);
}
} void getanc()
{
for (int i=;i<DEG;i++)
for (int j=;j<=n;j++)
{
anc[j][i]=anc[anc[j][i-]][i-];
maxlen[j][i]=max(maxlen[j][i-],maxlen[anc[j][i-]][i-]);
}
} int swim(int x,int H,int &ret)
{
for (int i=;H>;i++)
{
if (H&) ret=max(ret,maxlen[x][i]),x=anc[x][i];//swim过程中不要忘记更新ret
H/=;
}
return x;
} int lca(int a,int b)
{
int ret=-;
if (dep[a]<dep[b]) swap(a,b);
a=swim(a,dep[a]-dep[b],ret);
if (a==b) return ret;
for (int i=DEG-;i>=;i--)
{
if (anc[a][i]!=anc[b][i])
{
ret=max(ret,maxlen[a][i]);
a=anc[a][i];
ret=max(ret,maxlen[b][i]);
b=anc[b][i];
}
}
ret=max(ret,maxlen[a][]);//最后一条和父亲的连边不要忘记
ret=max(ret,maxlen[b][]);
return (ret);
} void init()
{
scanf("%d%d%d",&n,&m,&k);
for (int i=;i<=m;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
for (int i=;i<=n;i++) u[i]=i,h[i]=;
} void kruskal()
{
sort(edge+,edge+m+);
for (int i=;i<=m;i++)
{
int a=edge[i].u,b=edge[i].v;
int fa=find(a),fb=find(b);
if (fa!=fb)
{
union_set(fa,fb);
addedge(edge[i].u,edge[i].v,edge[i].w);
}
}
} void query()
{
dfs(,,);
getanc();
for (int i=;i<k;i++)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",lca(a,b));
}
} int main()
{
init();
kruskal();
query();
return ;
}
【LCA+MST】BZOJ3732-Network的更多相关文章
- 【kruscal】【最小生成树】【块状树】bzoj3732 Network
跟去年NOIP某题基本一样. 最小生成树之后,就变成了询问连接两点的路径上的权值最大的边. 倍增LCA.链剖什么的随便搞. 块状树其实也是很简单的,只不过每个点的点权要记录成“连接其与其父节点的边的权 ...
- 【LOJ#572】Misaka Network 与求和(莫比乌斯反演,杜教筛,min_25筛)
[LOJ#572]Misaka Network 与求和(莫比乌斯反演,杜教筛,min_25筛) 题面 LOJ \[ans=\sum_{i=1}^n\sum_{j=1}^n f(gcd(i,j))^k\ ...
- 【洛谷】【lca+结论】P3398 仓鼠找sugar
[题目描述:] 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室 ...
- 【LCA/tarjan】POJ1470-Closest Common Ancestors
[题意] 给出一棵树和多组查询,求以每个节点为LCA的查询数有多少? [错误点] ①读入的时候,注意它的空格是随意的呀!一开始不知道怎么弄,后来看了DISCUSS区大神的话: 询问部分输入: scan ...
- 【LCA倍增】POJ1330-Nearest Common Ancestors
[知识点:离线算法&在线算法] 一个离线算法,在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果. 一个在线算法是指它可以以序列化的方式一个个的处理输入,也就是说在开始 ...
- 【poj 1962】Corporative Network(图论--带权并查集 模版题)
P.S.我不想看英文原题的,但是看网上题解的题意看得我 炒鸡辛苦&一脸懵 +_+,打这模版题的代码也纠结至极了......不得已只能自己翻译了QwQ . 题意:有一个公司有N个企业,分成几个网 ...
- 【UVA 10369】 Arctic Network (最小生成树)
[题意] 南极有n个科研站, 要把这些站用卫星或者无线电连接起来,使得任意两个都能直接或者间接相连.任意两个都有安装卫星设备的,都可以直接通过卫星通信,不管它们距离有多远. 而安装有无线电设备的两个站 ...
- 【35.86%】【POJ 1962】Corporative Network
Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 3943 Accepted: 1414 Description A very bi ...
- 【LCA&倍增】货物运输 @upcexam5909
时间限制: 1 Sec 内存限制: 128 MB 题目描述 在一片苍茫的大海上,有n座岛屿,岛屿与岛屿之间由桥梁连接,所有的岛屿刚好被桥梁连接成一个树形结构,即共n-1架桥梁,且从任何一座岛屿出发都能 ...
随机推荐
- openstack项目【day23】:虚拟化介绍
本节内容 一 什么是虚拟化 二 为何要学习虚拟化 三 虚拟化技术主要分类(了解) 四 平台虚拟化技术又可以细分(了解) 一 什么是虚拟化 虚拟化说白了就是本来是一个完整的资源,切分或者说虚拟成多份,让 ...
- spring JMS在接收消息的时候总是报错
spring JMS在接收消息的时候总是报错 org.springframework.jms.UncategorizedJmsException: Uncategorized exception oc ...
- python技巧 is 和 ==
is 判断变量是否指向同一个对象 == 判断变量引用的对象是否相等 In [2]: a=[1,2] In [3]: b=a In [4]: a == b Out[4]: True In [5]: a ...
- 记webpack下进行普通模块化开发基础配置(自动打包生成html、多入口多页面)
写本记时(2018-06-25)的各版本 "webpack": "^4.6.0" //可直接使用4x以上的开发模式,刷新很快 "webpack-de ...
- ZYNQ. Interrupt(1)Private Timer
Interrupt zynq的中断. The PS is based on ARM architecture, utilizing two Cortex-A9 processors(CPUs) and ...
- Python输出9*9 乘法表
for i in range(1,10): for j in range(1,i+1): print(str(j) + str("*") + str(i)+"=" ...
- makefile 中 foreach
四.foreach 函数 foreach函数和别的函数非常的不一样.因为这个函数是用来做循环用的,Makefile中的foreach函数几乎是仿照于Unix标准Shell(/bin/sh)中的for语 ...
- 关于sudo 权限被修改的解决方法
在用sudo安装文件的时候,出现如下错误提示: sudo: /etc/sudoers is world writable sudo: no valid sudoers sources found, q ...
- 启动tomcat的时候爆出如下错误
The JRE_HOME environment variable is not defined correctly This environment 解决办法: https://blog.csdn. ...
- Java 协变返回类型
协变返回类型表示在导出类的被覆盖方法可以返回基类方法的返回类型的某种导出类型 //: polymorphism/covarianreturn.java package object; class Gr ...