cf 1051F 树+图
$des$
给定一张 $n$ 个点 $m$ 条边的带权无向联通图,$q$ 次询问,每次询问 $u_i$ 到 $v_i$ 的最短
路长度。
$n,q <= 10^5, m - n <= 20$
$sol$
首先随便搞一棵生成树,那么会有一些边不在生成树上。
把这些边的端点标记为特殊点。
对于一个询问,如果最短路只经过生成树上的边,就可以直接计算。
否则一定经过了一个特殊点,可以枚举这个特殊点,然后更新答案
$code$
#include <bits/stdc++.h> using namespace std; #define gc getchar()
inline int read() {
int x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x; } #define LL long long
#define Rep(i, a, b) for(int i = a; i <= b; i ++) const int N = 1e5 + ; int Now;
int cnt, head[N], cnt2, head2[N];
struct Node {
int u, v, w, nxt;
bool used;
} E[N], Gr[N << ], G[N << ]; int n, m;
int Nottree[], tot; int fat[N]; int Get(int x) {
return fat[x] == x ? x : fat[x] = Get(fat[x]);
} void Link(int u, int v, int w) {
G[++ cnt].v = v; G[cnt].w = w; G[cnt].nxt = head[u]; head[u] = cnt;
} void Link_g(int u, int v, int w) {
Gr[++ cnt2].v = v; Gr[cnt2].w = w; Gr[cnt2].nxt = head2[u]; head2[u] = cnt2;
} void Kruskal() {
int js = ;
Rep(i, , m) {
int u = E[i].u, v = E[i].v;
int fau = Get(u), fav = Get(v);
if(fau != fav) {
fat[fau] = fav;
js ++;
Link(u, v, E[i].w);
Link(v, u, E[i].w);
E[i].used = ;
}
if(js == n - ) break;
}
} struct Short {
LL u, dis_;
bool operator < (const Short a) const {
return this-> dis_ > a.dis_;
}
};
LL dis[][N];
bool vis[N];
priority_queue <Short> Q; void Dijkstra(int start) {
Rep(i, , n) dis[Now][i] = 1e18, vis[i] = ;
Q.push((Short) {start, dis[Now][start] = });
while(!Q.empty()) {
Short tp = Q.top();
Q.pop();
if(vis[tp.u]) continue;
vis[tp.u] = ;
for(int i = head2[tp.u]; ~ i; i = Gr[i].nxt) {
int v = Gr[i].v;
if(dis[Now][v] > dis[Now][tp.u] + Gr[i].w) {
dis[Now][v] = dis[Now][tp.u] + Gr[i].w;
Q.push((Short) {v, dis[Now][v]});
}
}
}
} int fa[N], size[N], son[N], topp[N];
LL deep[N]; void Dfs1(int u, int f_, LL dep) {
size[u] = ; fa[u] = f_; deep[u] = dep;
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(v == f_) continue;
Dfs1(v, u, dep + G[i].w);
size[u] += size[v];
if(size[v] > size[son[u]]) son[u] = v;
}
} void Dfs2(int u, int tp) {
topp[u] = tp;
if(!son[u]) return ;
Dfs2(son[u], tp);
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(v != fa[u] && v != son[u]) Dfs2(v, v);
}
} inline int Lca(int x, int y) {
int tpx = topp[x], tpy = topp[y];
while(tpx != tpy) {
if(deep[tpx] < deep[tpy]) swap(x, y), swap(tpx, tpy);
x = fa[tpx], tpx = topp[x];
}
if(deep[x] < deep[y]) swap(x, y);
return y;
} int main() {
n = read(), m = read();
Rep(i, , n) head[i] = -, head2[i] = -;
Rep(i, , n) fat[i] = i;
Rep(i, , m) {
int u = read(), v = read(), w = read();
E[i] = (Node) {u, v, w, , };
Link_g(u, v, w), Link_g(v, u, w);
} Kruskal();
Rep(i, , m) if(E[i].used == ) Nottree[++ tot] = E[i].u, Nottree[++ tot] = E[i].v; Rep(i, , tot) {
Now ++;
Dijkstra(Nottree[i]);
} Dfs1(, , );
Dfs2(, ); for(int q = read(); q; q --) {
int u = read(), v = read();
LL Answer = deep[u] + deep[v] - * deep[Lca(u, v)];
Rep(i, , tot) {
Answer = min(Answer, dis[i][u] + dis[i][v]);
}
cout << Answer << '\n';
} return ;
}
cf 1051F 树+图的更多相关文章
- CF 1051F
题意:给定一张n个点,m条边的无向联通图,其中m-n<=20,共q次询问,每次询问求给定两点u,v间的最短路长度 第一眼看见这题的时候,以为有什么神奇的全图最短路算法,满心欢喜的去翻了题解,发现 ...
- POJ2513(字典树+图的连通性判断)
//用map映射TLE,字典树就AC了#include"cstdio" #include"set" using namespace std; ; ;//26个小 ...
- CF 61E 树状数组+离散化 求逆序数加强版 三个数逆序
http://codeforces.com/problemset/problem/61/E 题意是求 i<j<k && a[i]>a[j]>a[k] 的对数 会 ...
- 树&图 记录
A - Lake Counting POJ - 2386 最最最最最基础的dfs 挂这道题为了提高AC率(糖水不等式 B - Paint it really, really dark gray Cod ...
- DS树+图综合练习--构建邻接表
题目描述 已知一有向图,构建该图对应的邻接表.邻接表包含数组和单链表两种数据结构,其中每个数组元素也是单链表的头结点,数组元素包含两个属性,属性一是顶点编号info,属性二是指针域next指向与它相连 ...
- DS树+图综合练习--二叉树之最大路径
题目描述 给定一颗二叉树的逻辑结构(先序遍历的结果,空树用字符‘0’表示,例如AB0C00D00),建立该二叉树的二叉链式存储结构 二叉树的每个结点都有一个权值,从根结点到每个叶子结点将形成一条路径, ...
- DS树+图综合练习--带权路径和
题目描述 计算一棵二叉树的带权路径总和,即求赫夫曼树的带权路径和. 已知一棵二叉树的叶子权值,该二叉树的带权案路径和APL等于叶子权值乘于根节点到叶子的分支数,然后求总和.如下图中,叶子都用大写字母表 ...
- cf 911F 树的直径+贪心
$des$ 给定一棵 n 个节点的树,你可以进行 n ? 1 次操作,每次操作步骤如下:选择 u,v 两个度数为 1 的节点.将 u,v 之间的距离加到 ans 上.将 u 从树上删除.求一个操作序列 ...
- 数据结构 B-树和B+树的应用:数据搜索和数据库索引
B-树 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点 ...
随机推荐
- Docker学习笔记(一)—— 概述
1. Docker是个什么玩意 说Docker是什么之前,先来看一看Docker为什么会出现.我们知道,在学习过程中我们需要频繁地安装配置一些软件,不管是在Windows下还是在Linux,这些东西的 ...
- 树莓派Raspbian系统格式化挂载硬盘
1.查看树莓派系统挂载的储存设备 使用工具查看系统识别到的硬盘设备,命令: fdisk -l /dev/sda 和 /dev/sdb 分别是两块硬盘. 2.修改硬盘分区 Linux和windows一 ...
- Java并发多线程面试题 Top 50
不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开发职位都要求开发者精通多线程 ...
- Java High Level REST Client 使用示例
概述 ES 在 7.0 版本开始将废弃 TransportClient,8.0 版本开始将完全移除 TransportClient,取而代之的是 High Level REST Client,官方文档 ...
- Vue异步加载高德地图API
项目中用到了高德地图的API以及UI组件库,因为是直接把引入script写在index.html中,项目打包后运行在服务器,用浏览器访问加载第一次时会非常慢,主要原因是加载高德地图相关的js(近一分钟 ...
- src属性与浏览器渲染
img标签 只要设置了src属性, 就会开始下载,因此可以使用这个特性,配合display:none,默默的下载一些图片,用的时候直接用,快了那么一丢丢~ 注意:不一定要添加到文档后才会开始下载,是只 ...
- WIN7U X64环境下的SQL SERVER 2008R2的防火墙配置
测试需要,备忘. CMD下运行,可以把sql server 要用的端口都开好. netsh advfirewall firewall add rule name = SQLPort dir = in ...
- day26-python之封装
1.动态导入模块 # module_t=__import__('m1.t') # print(module_t) # module_t = __import__('m1.t') # print(mod ...
- 隐藏Apache版本号及版本敏感信息
在安装软件前,我们需要隐藏软件的版本号及版本其他信息,这样就大大提高了安全指数. 只隐藏版本号: 我们在主配置文件里:httpd.conf [root@bqh- ~]# curl -i bbs.bqh ...
- Spark运行原理【史上最详细】
https://blog.csdn.net/lovechendongxing/article/details/81746988 Spark应用程序以进程集合为单位在分布式集群上运行,通过driver程 ...