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条双向光缆.每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传 ...
随机推荐
- Android APK 签名比对(转)
Android apk签名的过程 1. 生成MANIFEST.MF文件: 程序遍历update.apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个生成SHA1的数字签名信息,再用Ba ...
- C# WPF xml序列化 反序列化
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- 20155323刘威良《网络对抗》Exp9 Web安全基础
20155323刘威良<网络对抗>Exp9 Web安全基础 实践目的 理解常用网络攻击技术的基本原理. 实践内容 Webgoat实践下相关实验. 实践过程 开启WebGoat WebGoa ...
- 《图说VR入门》——DeepoonVR的大鹏(陀螺仪)枪
<图说VR入门>--VR大朋的(陀螺仪)枪 本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接: http://blog.csdn.net/cartzhang/ar ...
- Jmeter(十九)_ForEach控制器实现网页爬虫
一直以来,爬虫似乎都是写代码去实现的,今天像大家介绍一下Jmeter如何实现一个网页爬虫! 龙渊阁测试开发家园 317765580 Jmeter的爬虫原理其实很简单,就是对网页提交一个请求,然后把返回 ...
- Python中 list, numpy.array, torch.Tensor 格式相互转化
1.1 list 转 numpy ndarray = np.array(list) 1.2 numpy 转 list list = ndarray.tolist() 2.1 list 转 torch. ...
- Android与Unity相互调用
1. 在Unity里调用Android代码: void OnGUI(){ AndroidJavaClass jc = new AndroidJavaClass("com.some.packa ...
- PAT甲题题解-1064. Complete Binary Search Tree (30)-中序和层次遍历,水
由于是满二叉树,用数组既可以表示父节点是i,则左孩子是2*i,右孩子是2*i+1另外根据二分搜索树的性质,中序遍历恰好是从小到大排序因此先中序遍历填充节点对应的值,然后再层次遍历输出即可. 又是一道遍 ...
- uc浏览器app点评
uc浏览器app我经常用,是我接触的第一款手机浏览器,感觉还不错的,uc浏览器新闻更新速度有点慢,有时候还闪退,以前在搜索栏粘贴文字后,如果想改后面的文字,根本就不行,用uc浏览器下东西速度比较慢,现 ...
- 2-Eleventh Scrum Meeting20151211
第二阶段任务分工整理会议 1.会议任务: (1)明晰第二阶段的开发内容,统计未完成的功能留需完善开发. (2)安排任务分工,每个人的工作安排. (3)PM职位担任. (4)博客内容负责. 2.会议记录 ...