cf 1051F The Shortest Statement

开源项目 ruoyi-sso-oauth2(一)环境配置 Ruoyi若依实现单点登录SSO、oauth2认证 阅读详情

一 原题

F. The Shortest Statement

time limit per test: 4 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

You are given a weighed undirected connected graph, consisting of nn vertices and mm edges.

You should answer qq queries, the ii-th query is to find the shortest distance between vertices uiui and vivi.

Input

The first line contains two integers nn and m (1≤n,m≤105,m−n≤20)m (1≤n,m≤105,m−n≤20) — the number of vertices and edges in the graph.

Next mm lines contain the edges: the ii-th edge is a triple of integers vi,ui,di (1≤ui,vi≤n,1≤di≤109,ui≠vi)vi,ui,di (1≤ui,vi≤n,1≤di≤109,ui≠vi). This triple means that there is an edge between vertices uiui and vivi of weight didi. It is guaranteed that graph contains no self-loops and multiple edges.

The next line contains a single integer q (1≤q≤105)q (1≤q≤105) — the number of queries.

Each of the next qq lines contains two integers uiui and vi (1≤ui,vi≤n)vi (1≤ui,vi≤n) — descriptions of the queries.

Pay attention to the restriction m−n ≤ 20m−n ≤ 20.

Output

Print qq lines.

The ii-th line should contain the answer to the ii-th query — the shortest distance between vertices uiui and vivi.

Examples

input

Copy

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

output

Copy

3
4
1

二 分析

给你一个有1e5顶点的无向连通图,图里的边数最多比定点数多20。要处理1e5次查询,每次查询给定图上的两个点,返回这两个点的最短路长度。

如果没有边数的限制,那只能跑dijkstra或floyd。有这个限制的话,这个图就非常接近一棵树。树上两个点的简单路径是唯一的,求一下lca就可以了。但是生成树外最多还有20+1条边,把这些边的顶点记在一个集合里。如果最优解需要用到生成树之外的边,那么最短路径一定经过集合中的某个点,预处理时对这最多42个点各跑一次dijkstra。预处理lca复杂度O(nlgn),一次dijkstra复杂度O(nlgn+m)。单次查询复杂度是求lca的O(lgn)。

还真没见过一道CF题要写三个基础算法:并查集求生成树,最短路,LCA。。

 

三 代码

/*=====================================
*   
*   AUTHOR : maxkibble
*   CREATED: 2018.09.29 10:52:24
*
=====================================*/


#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, int> pli;

const int maxn = 1e5 + 5;
const int maxd = 20;
const int maxc = 45;
const ll inf = 1e15;

int n, m;
bool use[maxn];
int dep[maxn];
ll dis[maxn];
ll dijk_dis[maxc][maxn]; int cnt = 0;
int fa[maxd][maxn];
vector<pii> a[maxn];

struct Edge {
  int fr, to, len;
};

struct DSU {
  vector<int> f;
  set<int> st;
  
  DSU(int num) {
    for (int i = 0; i <= num; i++) f.pb(i);
  }
  
  int getF(int x) {
    return f[x] == x? x: f[x] = getF(f[x]);
  }
  
  void add(int x, int y, int i) {
    int fx = getF(x), fy = getF(y);
    if (fx == fy) {
      st.insert(x);
      st.insert(y);
    } else {
      if (fx > fy) swap(fx, fy);
      f[fy] = fx;
      use[i] = true;
    }
  }
};

void dfs(int cur, int pre, int distance) {
  dep[cur] = dep[pre] + 1;
  dis[cur] = dis[pre] + distance;
  fa[0][cur] = pre;
  for (auto nxt: a[cur]) {
    if (nxt.fi == pre) continue;
    dfs(nxt.fi, cur, nxt.se);
  }
}

int lca(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  int i = 0, d = dep[x] - dep[y];
  while (d) {
    if (d & 1) x = fa[i][x];
    i++;
    d >>= 1;
  }
  if (x == y) return x;
  for (int i = maxd - 1; i >= 0; i--) {
    if (fa[i][x] != fa[i][y]) {
      x = fa[i][x];
      y = fa[i][y];
    }
  }
  return fa[0][x];
}

void dijkstra(int st) {
  for (int i = 1; i <= n; i++) {
    dijk_dis[cnt][i] = inf;
  }
  dijk_dis[cnt][st] = 0;
  priority_queue<pli, vector<pli>, greater<pli>> q;
  for (auto item: a[st]) {
    q.push({item.se * 1ll, item.fi});
  }
  for (int i = 0; i < n - 1; i++) {
    // connected graph, no need to worry empty
    while (dijk_dis[cnt][q.top().se] != inf) q.pop();
    pli hd = q.top();
    dijk_dis[cnt][hd.se] = hd.fi;
    for (auto item: a[hd.se]) {
      q.push({hd.fi + item.se, item.fi});
    }
  }
  cnt++;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  cin >> n >> m;
  vector<Edge> e(m);
  for (int i = 0; i < m; i++) {
    cin >> e[i].fr >> e[i].to >> e[i].len;
    a[e[i].fr].pb({e[i].to, e[i].len});
    a[e[i].to].pb({e[i].fr, e[i].len});
  }
  DSU dsu(n);
  for (int i = 0; i < m; i++) {
    dsu.add(e[i].fr, e[i].to, i);
  }
  for (auto item: dsu.st) {
    dijkstra(item);
  }
  for (int i = 1; i <= n; i++) {
    a[i].clear();
  }
  for (int i = 0; i < m; i++) {
    if (!use[i]) continue;
    a[e[i].fr].pb({e[i].to, e[i].len});
    a[e[i].to].pb({e[i].fr, e[i].len});
  }
  dfs(1, 0, 0);
  for (int i = 1; i < maxd; i++) {
    for (int j = 1; j <= n; j++) {
      fa[i][j] = fa[i - 1][fa[i - 1][j]];
    }
  }
  int q;
  cin >> q;
  while (q--) {
    int x, y;
    cin >> x >> y;
    ll ans = dis[x] + dis[y] - dis[lca(x, y)] * 2;
    for (int i = 0; i < cnt; i++) {
      ll tmp = dijk_dis[i][x] + dijk_dis[i][y];
      ans = min(ans, tmp);
    }
    cout << ans << endl;
  }
  return 0;
}

 

Workbuddy+DeepSeek V4傻瓜流配置全指南:API接入、模型切换与Agent实战 AI编程助手的核心价值不在于模型本身,而在于如何稳定、安全、低门槛地调用其能力。Agent作为智能体范式,依赖可靠的运行时环境与标准化API通信;DeepSeek V4系列凭借高吞吐、低延迟和强工具调用支持,成为当前生产级Agent的理想引擎。Workbuddy则通过本地配置管理、环境变量注入与UTF-8无BOM容错等工程设计,将复杂部署简化为可复现、可版本化、可团队协同的实践流程。本文聚焦API接入路径下的真实卡点——从Key获取验证、models.json字段语义到沙箱权限控制,覆盖开发者在Window 阅读详情

相关推荐

Markdown编辑器介绍

这篇文章介绍了Markdown编辑器的功能和使用方法。主要内容包括:Markdown的基本语法如标题、列表、链接插入等;新增功能如图片拖拽、数学公式支持、甘特图和UML图表绘制;常用快捷键说明;以及文本导出导入操作。文章详细说明了如何通过Markdown语法实现文本格式化、代码高亮、表格创建等功能,并提供了多种图表绘制的语法示例,帮助用户更好地利用Markdown编辑器进行写作和内容创作。

soso1968的博客 1178

The Shortest Statement,LCA

You are given a weighed undirectedconnectedgraph, consisting ofnnvertices andmmedges. You should answerqqqueries, theii-th query is to find the shortest distance between verticesuiuiandviv...

xing_mo的博客 341

项目方案:社会视频资源整合接入汇聚系统解决方案(五)

视频监控接入和视频汇聚平台,形成整合平台,平台服务层包括编码设备、存储设备、解码设备等的接入服务,提供基础视频服务、传输服务、存储服务、控制服务及事件服务。两种不同的接入方式:监控设备接入,是指接入社会单位视频监控系统的DVR(数字硬盘录像机)、DVS和IPC、DVR/NVR、CVR等设备;平台对接,是指对接接入社会单位数字视频监控平台。AS-VAG视频监控接入网关支持onvif、国标等接入,也支持多种SDK接入方式,包括国产的主流品牌支持海康、大华、宇视、华为等SDK,国际品牌支持松下和axis等SDK。

weixin_70208651的博客 2464

CF1051F The Shortest Statement

CF1051F The Shortest Statement

Water_Problem的博客 773

SAP BTP-Cloud foundry 构建并部署JAVA应用程序

本文为 SAP BTP Java 应用程序的简单实例, 我们可以用此实例来熟悉SAP BTP 中的java应用开开发流程.在你完成改示例java应用程序以后, 我们可以直接使用该java应用程序进行后续的开发流程, 或直接构建一个新的JAVA应用程序来支持新的业务开发。

seyafly的博客 803

音频DSP开发中的‘隐藏关卡’:那些SigmaStudio未公开的模块计算秘籍

本文深入探讨音频DSP开发中SigmaStudio未公开的模块计算秘籍,重点解析动态范围控制、均衡器参数映射和混响算法优化等核心模块计算公式。通过实际案例揭示如何利用这些非官方技巧提升音频质量与系统性能,为ADI DSP开发者提供宝贵的实战经验。

water的专栏 911

The Shortest Statement //最短路+lca

题目链接:https://codeforces.com/problemset/problem/1051/F 题意:一个图由若干顶点和若干边组成,且说边的个数减去顶点的个数不会多于二十,有很多组点对,问这些点对的最短距离为多少。 解析:询问次数较多,不能每次都跑dij,由于题目给出边的个数减去顶点的个数不会多于二十,说明如果以原图去掉一些边建dfs树,最多要删21条边,所以可以把这些多余的边单...

wqq的博客 237

C#串口通信从入门到精通(7)——整数/浮点数与二进制、八进制、十六进制之间的转换与C#实现

本文详细介绍由博主开发的DataConvert串口通信帮助类的用法,该帮助类涵盖了串口通信领域所有的数据转换方法,帮助大家快速编写串口通信程序!

qq_34059233的博客 2879

F. The Shortest Statement(图论 树上加边)

http://codeforces.com/problemset/problem/1051/F 题意: 给出n个点,m条边,m−n≤20m-n\leq 20m−n≤20,边权。每次询问两个点之间的距离。 解析: 相当于树上添加21条边。对于一对点,原树上的距离可以用lca算出。考虑通过新加的边的路径。我们可以对涉及到的点,建立一个新的图(最多44个点),每次在新图跑一个最短路即可。 代码: #in...

QAQ 649

【常见开源库的二次开发】基于openssl的加密与解密——openssl认识与配置(一)

OpenSSL 是一个开源的软件库,它提供了一系列加密工具和协议,主要用于实现安全通信,如在网络上的数据传输。它支持多种加密算法,包括对称加密、非对称加密、散列函数、伪随机数生成器、数字签名、密钥交换以及证书管理等。

嵌入式技术开发 4161

华为od 面试八股文_C语言_01_含答案

华为od 面试八股文_C语言_01_含答案

MISAYAONE的博客 3225

codeforces - F. The Shortest Statement

F. The Shortest Statement time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard output You are given a weighed undirected connected graph, consisting of n ...

青烟绕指柔的博客 496

抓包网络调试工具 reqable抓包教程

如果CA根证书未安装成功,网络图标是黄色,点击盾牌图标可以进入CA根证书安装界面,详细步骤请阅读。在API调试中,获取流量是第一步也是最基本的操作,这里讲解下如何使用Reqable获取流量,通俗地讲就是抓包。我们可以选择一个图片请求,双击打开详情面板,能够看到该请求的详细信息。如果系统代理未设置,网络图标是黄色,点击网络图标可以自动设置系统代理。此域名的结构树,可以查看该域名下所有请求的目录结构,点击选择可以查看该请求的详情。首先,需要启用Reqable的调试功能,点击最右上角的。打开浏览器,输入地址。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 2556

[CF1051F]The Shortest Statement

思考,再思考,再思考。

七代目鸽影 207

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

[CF 1051F] The Shortest Statement

也许是最后的几篇题解了

ICEEBBING的博客 361

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

CF1051F The Shortest Statement [最短路]

传送门 注意到 m - n <= 20, 这意味着我们可以先dfs出一棵树,然后对于这m-n+1条边特殊考虑 我们发现,m-n+1条边最多40个点,那么我们对于这40个点暴力跑以它们为原点的最短路 查询时两个点的最短路要么在树上,要么经过这些特殊点,我们枚举这些特殊点就可以了 #include<bits/stdc++.h> #define N 200050 using ...

FSYo 的博客 243

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【题解】Luogu CF1051F The Shortest Statement

原题传送门:CF1051F The Shortest Statement 题目大意,给你一个稀疏图,q次查询,查询两点之间距离 边数减点小于等于20 这不是弱智题吗,23forever dalao又开始虐题 作为蒟蒻的我只能在一旁出售烤绿鸟和main包,和大家一起吃西瓜 仔细想想,这题的确是很弱智 先随便找一个生成树,这样就能跑lca了 剩下的几条边的端点跑一下SPFA堆优化dij,用于...

weixin_30613433的博客 145

题解 CF1051F 【The Shortest Statement】

这道题思路比较有意思,第一次做完全没想到点子上。。。 看到题目第一反应是一道最短路裸题,但是数据范围1e5说明完全不可能。 这个时候可以观察到题目给出了一个很有意思的条件,就是说边最多比点多20。 这有什么用呢? 那么我们大胆猜想,可否将整个图划分为21条边(连接最多42个点)和一颗树?(极限情况) 如果这样的话,对于任意的两个节点uv,它们之间的最短路只有两种情况: 这两个点都在树上。所以说...

weixin_34119545的博客 180

CF1051F The Shortest Statement Dijkstra+生成树

题意: 给定一张nnn个点mmm条边的图,qqq次询问两点之间的最短路 范围&性质:1≤n,m,q≤105,1≤m−n≤201\le n,m,q\le 10^5,1\le m-n\le 201≤n,m,q≤105,1≤m−n≤20 分析: 题面及其简洁,所以我们发现唯一显得很特别的一个条件就是1≤m−n≤201\le m-n\le 201≤m−n≤20 ,这个条件说明了什么,说明了整张图可以看做一棵树上多挂了几条边,所以我们只要对于特殊边所在的点跑一遍最短路,因为任意点对要么从树上走,要么必定经过这

youth518的博客 153

CF 1051 F. The Shortest Statement

F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意:   n个点,m条边的无向图,每次询问两点之间的最短路。(m-n<=20) 分析:   dijkstra。   如果是一棵树,那么可以直接通过,dis[u]+dis[v]-dis[lca]*2来求。现在如果建出一棵树,那么非树边...

weixin_30498921的博客 158

CF1051F The Shortest Statement Dijkstra + 性质分析

Code: #include<bits/stdc++.h> using namespace std; void setIO(string s) { string in=s+".in"; freopen(in.c_str(),"r",stdin); } typedef long long ll; const int max...

weixin_30799995的博客 112

[CF1051F] The Shortest Statement

CF 题目传送门 洛谷 题目传送门 一道最短路的题。 首先题目条件给出m-n<=20,可以看出这个图近乎一棵树。 首先跑出图的dfs树,预处理出树上距离等信息。 再枚举非树边,对每一个非树边的端点跑一边dijkstra。 可以看出最多有42个这样的点。 回答询问的时候,用树上距离作为答案,再用每一个非树边的端点更新答案即可。 1 #include<cstdio&...

weixin_30278237的博客 86
上一篇: cf 1027f Session in BSU
下一篇: cf 739B Alyona and a tree
max_kibble
博客等级 码龄11年 2粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值