BZOJ 2125: 最短路
2125: 最短路
Time Limit: 1 Sec Memory Limit: 259 MB
Submit: 756 Solved: 331
[Submit][Status][Discuss]
Description
给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径。
Input
输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个整数v,u,w表示一条无向边v-u,长度为w 最后Q行,每行两个整数v,u表示一组询问
Output
输出Q行,每行一个整数表示询问的答案
Sample Input
1 2 1
1 4 1
3 4 1
2 3 1
3 7 1
7 8 2
7 9 2
1 5 3
1 6 4
5 6 1
1 9
5 7
Sample Output
6
HINT
对于100%的数据,N<=10000,Q<=10000
Source
#include <cstdio>
#include <cstring> inline int nextChar(void)
{
static const int siz = << ; static char buf[siz];
static char *hd = buf + siz;
static char *tl = buf + siz; if (hd == tl)
fread(hd = buf, , siz, stdin); return int(*hd++);
} inline int nextInt(void)
{
int r = , c = nextChar(); for (; c < ; c = nextChar());
for (; c > ; c = nextChar())
r = r * + c - ''; return r;
} template <class T>
inline T min(const T &a, const T &b)
{
return a < b ? a : b;
} template <class T>
inline T abs(const T &x)
{
return x < ? -x : x;
} const int mxn = ;
const int inf = 0x3f3f3f3f; int n, m, q; int tot;
int hd[mxn];
int to[mxn];
int vl[mxn];
int nt[mxn]; inline void add(int x, int y, int w)
{
nt[tot] = hd[x];
to[tot] = y;
vl[tot] = w;
hd[x] = tot++;
} int dis[mxn];
int que[mxn];
int vis[mxn]; inline void spfa(void)
{
memset(vis, , sizeof vis);
memset(dis, inf, sizeof dis); int lt = , rt = ; que[rt++] = ;
vis[] = ;
dis[] = ; while (lt != rt)
{
int u = que[lt++], v; if (lt > mxn)lt = ; vis[u] = ; for (int i = hd[u]; ~i; i = nt[i])
if (v = to[i], dis[v] > dis[u] + vl[i])
{
dis[v] = dis[u] + vl[i]; if (!vis[v])
{
vis[que[rt++] = v] = ; if (rt > mxn)rt = ;
}
}
}
} struct data
{
int u, v, w; inline data(void) {};
inline data(int a, int b, int c)
: u(a), v(b), w(c) {};
}stk[mxn]; int top; int tim;
int dfn[mxn];
int low[mxn]; int cnt;
int cir[mxn];
int len[mxn];
int bel[mxn];
int fat[mxn][]; inline void addcir(int u, int v)
{
++cnt; while (u != stk[top].u && v != stk[top].v)
{
int x = stk[top].u, y = stk[top].v, w = stk[top].w; if (x != u)bel[x] = cnt, fat[x][] = u;
if (y != u)bel[y] = cnt, fat[y][] = u; len[cnt] += w, cir[x] = cir[y] + w; --top;
} {
int x = stk[top].u, y = stk[top].v, w = stk[top].w; len[cnt] += w, cir[x] = cir[y] + w; fat[y][] = x; --top;
}
} void tarjan(int u, int f)
{
dfn[u] = low[u] = ++tim; for (int i = hd[u], v; ~i; i = nt[i])
if ((v = to[i]) != f)
{
if (!dfn[v])
{
stk[++top] = data(u, v, vl[i]), tarjan(v, u); if (low[v] < low[u])low[u] = low[v]; if (low[v] >= dfn[u])addcir(u, v);
}
else if (dfn[v] < low[u])
low[u] = dfn[v], stk[++top] = data(u, v, vl[i]);
}
} int dep[mxn]; void build(int u)
{
for (int i = hd[u]; ~i; i = nt[i])
dep[to[i]] = dep[u] + , build(to[i]);
} inline void prework(void)
{
spfa(); tarjan(, ); for (int i = ; i <= ; ++i)
for (int j = ; j <= n; ++j)
fat[j][i] = fat[fat[j][i - ]][i - ]; memset(hd, -, sizeof hd), tot = ; for (int i = ; i <= n; ++i)
add(fat[i][], i, ); dep[] = , build();
} inline int getLCA(int a, int b, int &x, int &y)
{
if (dep[a] < dep[b])
a ^= b ^= a ^= b; int ret = dis[a] + dis[b]; for (int i = ; ~i; --i)
if (dep[fat[a][i]] >= dep[b])
a = fat[a][i]; if (a == b)
return x = y = a, ret - dis[a] * ; for (int i = ; ~i; --i)
if (fat[a][i] != fat[b][i])
a = fat[a][i],
b = fat[b][i]; return x = a, y = b, ret - dis[fat[a][]] * ;
} signed main(void)
{
n = nextInt();
m = nextInt();
q = nextInt(); memset(hd, -, sizeof(hd)), tot = ; for (int i = ; i <= m; ++i)
{
int x = nextInt();
int y = nextInt();
int w = nextInt(); add(x, y, w);
add(y, x, w);
} prework(); for (int i = , x, y; i <= q; ++i)
{
int a = nextInt();
int b = nextInt(); int ans = getLCA(a, b, x, y); if (bel[x] && bel[x] == bel[y])
{
ans = dis[a] + dis[b] - dis[x] - dis[y]; int len1 = abs(cir[x] - cir[y]);
int len2 = len[bel[x]] - len1; ans += min(len1, len2);
} printf("%d\n", ans);
}
}
@Author: YouSiki
BZOJ 2125: 最短路的更多相关文章
- bzoj 2125 最短路——仙人掌两点间最短路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2125 因为看了TJ又抄了标程,现在感觉还是轻飘飘的……必须再做一遍. 两点间的情况: 1.直 ...
- 【刷题】BZOJ 2125 最短路
Description 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. Input 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个 ...
- BZOJ.2125.最短路(仙人掌 最短路Dijkstra)
题目链接 多次询问求仙人掌上两点间的最短路径. 如果是在树上,那么求LCA就可以了. 先做着,看看能不能把它弄成树. 把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]. 对于 ...
- bzoj 2125 最短路 点双 圆方树
LINK:最短路 一张仙人掌图 求图中两点最短路. \(n<=10000,Q<=10000,w>=1\) 考虑边数是多少 m>=n-1 对于一张仙人掌图 考虑先构建出来dfs树 ...
- BZOJ.2125.最短路(仙人掌 圆方树)
题目链接 圆方树.做题思路不写了.. 就是当LCA是方点时跳进那个环可以分类讨论一下用树剖而不必须用倍增: 如果v是u的(唯一的那个)重儿子,那么u的DFS序上+1的点即是要找的:否则v会引出一条新的 ...
- bzoj 1023: [SHOI2008]cactus仙人掌图 2125: 最短路 4728: 挪威的森林 静态仙人掌上路径长度的维护系列
%%% http://immortalco.blog.uoj.ac/blog/1955 一个通用的写法是建树,对每个环建一个新点,去掉环上的边,原先环上每个点到新点连边,边权为点到环根的最短/长路长度 ...
- 【BZOJ】2125: 最短路 圆方树(静态仙人掌)
[题意]给定带边权仙人掌图,Q次询问两点间最短距离.n,m,Q<=10000 [算法]圆方树处理仙人掌问题 [题解]树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图. 先对仙人掌 ...
- Bzoj 3694: 最短路 树链剖分
3694: 最短路 Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 67 Solved: 34[Submit][Status][Discuss] Des ...
- bzoj3047: Freda的传呼机 && 2125: 最短路
Description 为了随时与rainbow快速交流,Freda制造了两部传呼机.Freda和rainbow所在的地方有N座房屋.M条双向光缆.每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传 ...
随机推荐
- VMware 克隆多台Linux机器并配置IP
1.查看并分配虚拟网络 我们首先要知道 VMware 三种网络模式的区别. ①.Bridged(桥接模式):就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信.在桥接的作用下,类似于把物理主机虚拟为 ...
- SonarQube-基本概念
组件组成 1.sonarqube server : 他有三个程序分别是 webserver(配置和管理sonar) searchserver(搜索结果返回给sonarUI) ComplateEng ...
- spring boot项目配置RestTemplate超时时长
配置类: @Configuration public class FeignConfiguration { @Bean(name="remoteRestTemplate") pub ...
- 在win10下使用docker快速搭建ruby开发环境
docker在windows下发力的时候必将取代各种虚拟机,并改变程序员的开发习惯,或许还会改变infra的工作. 概要: 在Windows下搭建开发环境一直是infra(我)头疼的事情.为了解决这个 ...
- 大数据入门第十五天——HBase整合:云笔记项目
一.功能简述 1.笔记本管理(增删改) 2.笔记管理 3.共享笔记查询功能 4.回收站 效果预览: 二.库表设计 1.设计理念 将云笔记信息分别存储在redis和hbase中. redis(缓存):存 ...
- 路遥眼里的河南人<平凡的世界>
路遥,一个作过农民,当过小学教师,用平凡的生命,却写出不平凡的小说<平凡的世界>,他喜欢夜的宁静,喜欢在夜里思考,他说只有在夜里我们才是最真实的自己.所以他喜欢在夜里创作,这部小说也是在这 ...
- Luogu P2483 【模板】k短路([SDOI2010]魔法猪学院)
说实话,看到这道题的洛谷评级我傻了(传说中的最高难度) 然后看完题目才确定这真的是一道k短路的裸题. 也就敲了个A*吧,15分钟竟然没有调试一遍过. 欧洲玄学. 看题目,主要是找几条从1走到n的路加起 ...
- HTML基础之CSS
CSS选择器 1.id选择器 2.class选择器 3.标签选择器 4.层级选择器(空格) 5.组合选择器(逗号) 6.属性选择器(中括号) <!DOCTYPE html> <htm ...
- [LOJ#2878]. 「JOISC 2014 Day2」邮戳拉力赛[括号序列dp]
题意 题目链接 分析 如果走到了下行车站就一定会在前面的某个车站走回上行车站,可以看成是一对括号. 我们要求的就是 类似 代价最小的括号序列匹配问题,定义 f(i,j) 表示到 i 有 j 个左括号没 ...
- 利用Python实现App自动签到领取积分
要自动签到,最简单的是打开页面分析请求,然后我们用脚本实现请求的自动化.但是发现食行没有页面,只有 APP,这不是一个好消息,这意味着需要抓包处理了. 有需要Python学习资料的小伙伴吗?小编整理[ ...