【题目大意】

给你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的更多相关文章

  1. 【kruscal】【最小生成树】【块状树】bzoj3732 Network

    跟去年NOIP某题基本一样. 最小生成树之后,就变成了询问连接两点的路径上的权值最大的边. 倍增LCA.链剖什么的随便搞. 块状树其实也是很简单的,只不过每个点的点权要记录成“连接其与其父节点的边的权 ...

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

  3. 【洛谷】【lca+结论】P3398 仓鼠找sugar

    [题目描述:] 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室 ...

  4. 【LCA/tarjan】POJ1470-Closest Common Ancestors

    [题意] 给出一棵树和多组查询,求以每个节点为LCA的查询数有多少? [错误点] ①读入的时候,注意它的空格是随意的呀!一开始不知道怎么弄,后来看了DISCUSS区大神的话: 询问部分输入: scan ...

  5. 【LCA倍增】POJ1330-Nearest Common Ancestors

    [知识点:离线算法&在线算法] 一个离线算法,在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果. 一个在线算法是指它可以以序列化的方式一个个的处理输入,也就是说在开始 ...

  6. 【poj 1962】Corporative Network(图论--带权并查集 模版题)

    P.S.我不想看英文原题的,但是看网上题解的题意看得我 炒鸡辛苦&一脸懵 +_+,打这模版题的代码也纠结至极了......不得已只能自己翻译了QwQ . 题意:有一个公司有N个企业,分成几个网 ...

  7. 【UVA 10369】 Arctic Network (最小生成树)

    [题意] 南极有n个科研站, 要把这些站用卫星或者无线电连接起来,使得任意两个都能直接或者间接相连.任意两个都有安装卫星设备的,都可以直接通过卫星通信,不管它们距离有多远. 而安装有无线电设备的两个站 ...

  8. 【35.86%】【POJ 1962】Corporative Network

    Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 3943 Accepted: 1414 Description A very bi ...

  9. 【LCA&倍增】货物运输 @upcexam5909

    时间限制: 1 Sec 内存限制: 128 MB 题目描述 在一片苍茫的大海上,有n座岛屿,岛屿与岛屿之间由桥梁连接,所有的岛屿刚好被桥梁连接成一个树形结构,即共n-1架桥梁,且从任何一座岛屿出发都能 ...

随机推荐

  1. C#_界面程序_数码游戏

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. H5 Day1 练习

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 前三章 man手册 查看文件

    1 – 3章 1.1 man手册: 分1 - 9个区域,可以认为是一个一个小节 把man手册理解为一本书 第一节:可执行程序或shell命令 第二节:系统调用 第三节:库调用 第四节:特殊文件 第五节 ...

  4. MySQL-视图View

    视图:一个非真实存在的,囊括复杂查询在内的表,也可以理解成,视图就是一个查询之后的结果. 补充一个概念:临时表查询(子查询):就是在查询语句中再次嵌套一个查询,并将嵌套中的查询设定别名 SELECT ...

  5. Markdown基础教程

    标题 Markdown支持6种级别的标题,对应html标签 h1 ~ h6

  6. ARM linux内核启动时几个关键地址【转】

    转自:http://www.cnblogs.com/armlinux/archive/2011/11/06/2396787.html 1.       内核启动地址1.1.   名词解释ZTEXTAD ...

  7. 【坐在马桶上看算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  8. centos7 部署 docker swarm

    =============================================== 2019/4/9_第3次修改                       ccb_warlock 更新说 ...

  9. 06 Go 1.6 Release Notes

    Go 1.6 Release Notes Introduction to Go 1.6 Changes to the language Ports Tools Cgo Compiler Toolcha ...

  10. 使用Windows 2008R2中的NFS替代Samba协议,解决Windows 与Linux共享文件的问题

    一.在Windows服务器上进行安装NFS服务 首先,打开服务管理器,选择添加角色:     选中文件服务,下一步:     出现一个提示,不管它,继续下一步:     在接下来的页面中选中“网络文件 ...