题目传送门(内部题131)


输入格式

  第一行三个整数$n$、$m$和$Q$。
  接下来$m$行每行三个整数$x$、$y$、$z$($1\leqslant x,y\leqslant n,1\leqslant z\leqslant 1,000,000$),表示有一条连接$x$和$y$长度为$z$的边。
  接下来$Q$行每行两个整数$x$、$y$($x\neq y$),表示一组询问。


输出格式

  $Q$行每行一个整数,表示一组询问的答案。


样例

样例输入:

5 5 4
1 2 3
1 3 2
3 2 1
1 4 5
2 4 4
1 2
1 4
3 5
2 4

样例输出:

2
4
-1
4


数据范围与提示

  对于前$30\%$的测试数据,满足$1\leqslant n,m,Q\leqslant 1,000$。
  对于另外$30\%$的测试数据,保证图联通。
  对于$100\%$的测试数据,满足$1\leqslant n,m,Q\leqslant 300,000$。
  对于$100\%$的测试数据,保证不存在自环,但可能存在重边。
  请使用$scanf,printf$或速度更快的读入输出方式。


题解

有人问我$30\%$的暴力怎么打(问题是$ta$还$A$了)……

那我就简单说一下。

最短路思想,用$Dijkstra$,将原本的$dis[v]=dis[u]+e[i].w$改成$dis[v]=\max(dis[u],e[i].w)$就好了。

千万不要想当然,比方说下面这份代码$\downarrow$

认真看一下,虽说时间复杂度是对的,但是如果如下面这张图$\downarrow$

我们可能会选择$x\stackrel{2}{\rightarrow}o\stackrel{1}{\rightarrow}y$这条路径;然而当发现$x\stackrel{1}{\rightarrow}o$更优时会发现$o\rightarrow y$已经走过了,就不会再更新答案,这也就是为什么最短路不是这么求。

现在来说正解吧,先来考虑联通的情况。

这个最优路径上的所有边一定位于最小生成树上,所以可以求$x,y$到$lca$上的最长边即可。

不联通的情况也无非就是记录一下两个点在不在一个联通块内即可。

时间复杂度:$\Theta(m\log m+q\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct node{int x,y,z;bool d;}b[300001];
struct rec{int nxt,to,w;}e[600001];
int head[300001],cnt,tot;
int n,m,Q;
int f[300001],depth[300001],bel[300001],fa[300001][21],mi[300001][21];
bool cmp(node a,node b){return a.z<b.z;}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void add(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void dfs(int x)
{
bel[x]=tot;
for(int i=head[x];i;i=e[i].nxt)
{
if(depth[e[i].to])continue;
depth[e[i].to]=depth[x]+1;
fa[e[i].to][0]=x;
mi[e[i].to][0]=e[i].w;
for(int j=1;j<=20;j++)
{
fa[e[i].to][j]=fa[fa[e[i].to][j-1]][j-1];
mi[e[i].to][j]=max(mi[e[i].to][j-1],mi[fa[e[i].to][j-1]][j-1]);
}
dfs(e[i].to);
}
}
int LCA(int x,int y)
{
if(depth[x]>depth[y])swap(x,y);
int res=0;
for(int i=20;i>=0;i--)
if(depth[fa[y][i]]>=depth[x])
{
res=max(res,mi[y][i]);
y=fa[y][i];
}
if(x==y)return res;
for(int i=20;i>=0;i--)
if(fa[x][i]!=fa[y][i])
{
res=max(res,max(mi[x][i],mi[y][i]));
x=fa[x][i];y=fa[y][i];
}
return max(res,max(mi[x][0],mi[y][0]));
}
int main()
{
scanf("%d%d%d",&n,&m,&Q);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++)scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].z);
sort(b+1,b+m+1,cmp);
for(int i=1;i<=m;i++)
{
int x=find(b[i].x);
int y=find(b[i].y);
if(x==y)continue;
b[i].d=1;
f[y]=x;
}
for(int i=1;i<=m;i++)
if(b[i].d)
{
add(b[i].x,b[i].y,b[i].z);
add(b[i].y,b[i].x,b[i].z);
}
for(int i=1;i<=n;i++)
if(!depth[i])
{
tot++;
depth[i]=1;
dfs(i);
}
while(Q--)
{
int x,y;
scanf("%d%d",&x,&y);
if(bel[x]!=bel[y])puts("-1");
else printf("%d\n",LCA(x,y));
}
return 0;
}

rp++

[CSP-S模拟测试]:小Y的图(最小生成树+LCA)的更多相关文章

  1. 5.19 省选模拟赛 小B的图 最小生成树 LCT

    LINK:小B的图 这道题就比较容易了. 容易想到将询问离线 然后 从小到大排序 那么显然是优先放正图(x+k)的边. 考虑随着x的增大 那么负图上的边会逐渐加进来 一条边被加进来当且仅当 其权值小于 ...

  2. noip模拟赛 小Y的问题

    [问题描述]有个孩子叫小 Y,一天,小 Y 拿到了一个包含 n 个点和 n-1 条边的无向连通图, 图中的点用 1~n 的整数编号.小 Y 突发奇想,想要数出图中有多少个“Y 字形”.一个“Y 字形” ...

  3. [CSP-S模拟测试]:小P的生成树(数学+Kruskal)

    题目描述 小$P$是个勤于思考的好孩子,自从学习了最大生成树后,他就一直在想:能否将边权范围从实数推广到复数呢?可是马上小$P$就发现了问题,复数之间的大小关系并没有定义.于是对于任意两个复数$z_1 ...

  4. [CSP-S模拟测试]:小P的2048(模拟)

    题目描述 最近,小$P$迷上了一款叫做$2048$的游戏.这块游戏在一个$n\times n$的棋盘中进行,棋盘的每个格子中可能有一个形如$2^k(k\in N^*)$的数,也可能是空的.游戏规则介绍 ...

  5. [CSP-S模拟测试]:小盆友的游戏(数学 or 找规律)

    题目传送门(内部题110) 输入格式 第一行一个整数$N$,表示小盆友的个数. 第二行$N$个整数$A_i$,如果$A_i=-1$表示$i$目前是自由身,否则$i$是$A_i$的跟班. 输出格式 一个 ...

  6. [CSP-S模拟测试]:小奇的仓库(warehouse)(树形DP)

    题目背景 小奇采的矿实在太多了,它准备在喵星系建个矿石仓库.令它无语的是,喵星系的货运飞船引擎还停留在上元时代! 题目描述 喵星系有$n$个星球,星球以及星球间的航线形成一棵树.从星球$a$到星球$b ...

  7. [CSP-S模拟测试]:小L的数(数位DP+模拟)

    题目传送门(内部题132) 输入格式 第一行一个整数$t$. 接下来$t$行每行一个整数$n$. 输出格式 $t$行,每行一个整数表示答案. 样例 样例输入: 41818231232691052109 ...

  8. [CSP-S模拟测试]:小W的魔术(数学 or 找规律)

    题目传送门(内部题130) 输入格式 第一行一个整数$n$,表示字符串的长度. 第二行一个只包含小写字母的字符串$s$. 输出格式 一行一个整数表示答案对$998244353$取模后的结果. 样例 样 ...

  9. [CSP-S模拟测试]:小P的单调数列(树状数组+DP)

    题目描述 小$P$最近喜欢上了单调数列,他觉得单调的数列具有非常多优美的性质.经过小$P$复杂的数学推导,他计算出了一个单调增数列的艺术价值等于该数列中所有书的总和.并且以这个为基础,小$P$还可以求 ...

随机推荐

  1. spark教程(12)-生态与原理

    spark 是目前非常流行的大数据计算框架. spark 生态 Spark core:包含 spark 的基本功能,定义了 RDD 的 API,其他 spark 库都基于 RDD 和 spark co ...

  2. idea 新建maven项目时,避免每次都需要指定自己的maven目录

    01 .File->Other Settings -> Settings for New Project 02. 将Maven home directory目录修改成我们自己安装Maven ...

  3. webAapi

    学习目标: 掌握API和Web API的概念 掌握常见浏览器提供的API的调用方式 能通过Web API开发常见的页面交互功能 能够利用搜索引擎解决问题 typora-copy-images-to: ...

  4. PHP扩展开发01:第一个扩展

    我们先假设业务场景,是需要有这么一个扩展,提供一个叫ccvita_string的函数,他的主要作用是返回一段字符.(这个业务场景实在太假,大家就这么看看吧)对应的PHP代码可能是这样: functio ...

  5. 动态表和C++ vector

    动态表和C++ vector 最近课上刚刚学了可以根据表中元素的插入和删除动态调整表大小的动态表(dynamic table),就想看一下它有什么实际的应用,第一个想起来的就是C++的vector,直 ...

  6. MySQL 的索引是什么?怎么优化?

    索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左右性能开始逐渐下降,虽然官方文档说500~800w记录,所以大数据量建立索引是非常有必要的.My ...

  7. 简单了解journalctl

    journalctl 命令 journalctl是什么以及作用? journalctl 用来查询 systemd-journald 服务收集到的日志.systemd-journald 服务是 syst ...

  8. jquery事件绑定方式总结(补充)

    总结 : 1.简单事件绑定方式:事件名()  如:click() 2.高级事件绑定方式:bind(事件名,数据参数,function)    3.动态生成元素事件绑定方式:live(事件名,数据参数, ...

  9. Linux centos :root密码忘记怎么办?

    1 重启系统后出现GRUB界面在引导装载程序菜单上,用上下方向键选择你忘记密码的那个系统键入“e” 来进入编辑模式. 2 接下来你可以看到如下图所示的画面,然后你再用上下键选择最新的内核(这里是第二行 ...

  10. Codeforces Round #581 (Div. 2) C. Anna, Svyatoslav and Maps (Floyd 算法,最短路)

    C. Anna, Svyatoslav and Maps time limit per test2 seconds memory limit per test256 megabytes inputst ...