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 棵子树:⑵若根结点不是叶子结点 ...
随机推荐
- [高清·非影印] Python机器学习经典实例(电子书+源码)
------ 郑重声明 --------- 资源来自网络,纯粹共享交流, 如果喜欢,请您务必支持正版!! --------------------------------------------- 下 ...
- JDBC使用8.0驱动包连接mysql设置时区serverTimezone
驱动包用的是新版 mysql-connector-java-8.0.16.jar新版的驱动类改成了com.mysql.cj.jdbc.Driver新版驱动连接url也有所改动I.指定时区 如果不设置时 ...
- MyEclipse的 lib和Build path(构建路径)
首先两种方式对于放置jar包的方式是不同的: Build path(构建路径):对于种方式来说,可以算是对jar包文件的一个引用.可以引用lib下的jar包,也可以引用本地磁盘上的jar包. WEB- ...
- IIS配置文件的XML格式不正确 applicationHost.config崩溃
错误提示如图: 检查C:\Windows\System32\inetsrv\config目录下的applicationHost.config文件,备份一份. 可使用IIS提供的AppCmd.exe的r ...
- Steam之两个list间交集、并集、差集
public static void main(String[] args) { List<String> list1 = new ArrayList(); list1.add(" ...
- SASS系列之:!global VS !deafult
先脑补两组场景. 场景一: 同事们每天中午都会外出吃饭.通常情况下都会先问,去哪儿吃啊?不知道啊?下楼再说吧.到了楼下好不容易有个人站出来说,既然没人说我可就说了啊,咱们去吃香草香草吧.没人反对就去, ...
- css选择符优先级
- svg实现圆环进度条
开源实现:https://github.com/lugolabs/circles 自行实现:圆环与svg画布间剩的空间太多. <!DOCTYPE html> <html> &l ...
- CDN详解
一.定义 背景: 当下的互联网应用都包含大量的静态内容,但静态内容以及一些准动态内容又是最耗费带宽的,特别是针对全国甚至全世界的大型网站,如果这些请求都指向主站的服务器的话,不仅是主站服务器受不了,单 ...
- iptables-1基本知识和工作原理
一.简介1.iptables的定义:防火墙分为硬件防火墙和软件防火墙.iptables是软件防火墙,工作在OSI的第三.四层,是从操作系统层面对网络流量进行监控和防护.延伸:(1)Linux系统内核集 ...