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

9 10 2
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

5
6

HINT

对于100%的数据,N<=10000,Q<=10000

Source

 

[Submit][Status][Discuss]

 #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: 最短路的更多相关文章

  1. bzoj 2125 最短路——仙人掌两点间最短路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2125 因为看了TJ又抄了标程,现在感觉还是轻飘飘的……必须再做一遍. 两点间的情况: 1.直 ...

  2. 【刷题】BZOJ 2125 最短路

    Description 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. Input 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个 ...

  3. BZOJ.2125.最短路(仙人掌 最短路Dijkstra)

    题目链接 多次询问求仙人掌上两点间的最短路径. 如果是在树上,那么求LCA就可以了. 先做着,看看能不能把它弄成树. 把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]. 对于 ...

  4. bzoj 2125 最短路 点双 圆方树

    LINK:最短路 一张仙人掌图 求图中两点最短路. \(n<=10000,Q<=10000,w>=1\) 考虑边数是多少 m>=n-1 对于一张仙人掌图 考虑先构建出来dfs树 ...

  5. BZOJ.2125.最短路(仙人掌 圆方树)

    题目链接 圆方树.做题思路不写了.. 就是当LCA是方点时跳进那个环可以分类讨论一下用树剖而不必须用倍增: 如果v是u的(唯一的那个)重儿子,那么u的DFS序上+1的点即是要找的:否则v会引出一条新的 ...

  6. bzoj 1023: [SHOI2008]cactus仙人掌图 2125: 最短路 4728: 挪威的森林 静态仙人掌上路径长度的维护系列

    %%% http://immortalco.blog.uoj.ac/blog/1955 一个通用的写法是建树,对每个环建一个新点,去掉环上的边,原先环上每个点到新点连边,边权为点到环根的最短/长路长度 ...

  7. 【BZOJ】2125: 最短路 圆方树(静态仙人掌)

    [题意]给定带边权仙人掌图,Q次询问两点间最短距离.n,m,Q<=10000 [算法]圆方树处理仙人掌问题 [题解]树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图. 先对仙人掌 ...

  8. Bzoj 3694: 最短路 树链剖分

    3694: 最短路 Time Limit: 5 Sec  Memory Limit: 256 MBSubmit: 67  Solved: 34[Submit][Status][Discuss] Des ...

  9. bzoj3047: Freda的传呼机 && 2125: 最短路

    Description 为了随时与rainbow快速交流,Freda制造了两部传呼机.Freda和rainbow所在的地方有N座房屋.M条双向光缆.每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传 ...

随机推荐

  1. 搭建Hadoop的HA高可用架构(超详细步骤+已验证)

    一.集群的规划 Zookeeper集群: 192.168.182.12 (bigdata12)192.168.182.13 (bigdata13)192.168.182.14 (bigdata14) ...

  2. 20155310《网络对抗》Exp2 后门原理与实践

    20155310<网络对抗>Exp2 后门原理与实践 基础问题回答 1.例举你能想到的一个后门进入到你系统中的可能方式? 在网上下载软件的时候,后门很有可能被捆绑在下载的软件当中: 浏览网 ...

  3. 20155321 《网络攻防》 Exp9 Web安全基础

    20155321 <网络攻防> Exp9 Web安全基础 基础问题 SQL注入攻击原理,如何防御 原理:在事先定义好的SQL语句的结尾上添加额外的SQL语句(感觉一般是或上一个永真式),以 ...

  4. 20155331《网络对抗》Exp7 网络欺诈防范

    20155331<网络对抗>Exp7 网络欺诈防范 实验内容 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有: 简单应用SET工具建立冒名网站 et ...

  5. 【WPF】两则动画效果

    原文:[WPF]两则动画效果 引言 利用WPF的动画可以轻而易举的实现各种各样的特效,如擦除,滑动进入等,先看两个效果图 第一个效果 这个动画其实利用了OpacityMask和LinearGradie ...

  6. 搭建 Guacamole 并解决各种坑和创建不了虚拟驱动器导致无法实现文件传输的方法

    系统类型版本:centos7 64位 结果:最终跑通了项目并且实现了虚拟驱动器的文件传输功能,添加了中文支持 反思总结: 先查看官方文档的Q&A,找找有没有类似的错误,然后如果有错误日志或者现 ...

  7. effective c++ 笔记 (23-25)

    //---------------------------15/04/08---------------------------- //#23   宁以non_member.non_friend替换m ...

  8. 前端示例MVC网站

    前端示例MVC网站 ASP.NET Zero 包含了一个公共web站点的前端页面和一个登陆页面.当您第一次运行项目的时候可以看到,如下图所示: 该前端网站有两个页面,一个是主页和关于我们.这些页面的内 ...

  9. Redis介绍及Jedis基础操作

    1.Redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes ...

  10. python3解析网页经过base64编码后的图片

    有时候我们打开网页看到的图片不是普通的url,例如:www.baidu.com/static/2.jpg,而是经过base64方式加密过的路径:例如:data:img/jpg;base64,/9j/4 ...