bzoj#2125. 最短路

题目描述

Description
给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径。
Input
输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个整数v,u,w表示一条无向边v-u,长度为w 最后Q行,每行两个整数v,u表示一组询问
Output
输出Q行,每行一个整数表示询问的答案

Solution

题意就是求仙人掌中两点最短路。

就是仙人掌圆方树的板子题。

对于每一个环用一个方点ttt代替环,从方点ttt向这个环的根节点xxx连一条代价为000的边,再从ttt向环上其他所有点yyy连一条代价为mindis(x,y)mindis(x,y)mindis(x,y)的边,并在ttt上记录整个环的总长度sumtsum_tsumt​。

每一次询问(x,y)(x,y)(x,y)最短路时,分类讨论LCA(x,y)LCA(x,y)LCA(x,y)是方点还是圆点。
若是圆点答案即为dist(x,y)dist(x,y)dist(x,y)。
若是方点,则答案为xxx到环的最短路+yyy到环的最短路+xxx接入环的节点与yyy接入环的节点之间的最短路。

因此只要倍增或树剖预处理出LCA与路径和,每次跳LCA的时候顺路求解答案即可。

时间复杂度O(nlg⁡n)O(n\lg n)O(nlgn)

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=1e9+7;
const int MAXN=30005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f;
}
struct enode{int to,c; };
vector<enode> e[MAXN],E[MAXN];
int DFN=0,n,m,Case,num,dist[MAXN],sum[MAXN],Fa[MAXN],flag[MAXN];
int dfn[MAXN],low[MAXN],fa[MAXN][15],sm[MAXN][15],dep[MAXN],Log[MAXN];
void add_edge(int x,int y,int c)
{//  cout<<"Edge:"<<x<<" "<<y<<" "<<c<<endl;E[x].PB(((enode){y,c}));E[y].PB(((enode){x,c}));
}
void solve(int x,int y,int c)
{sum[++num]=dist[y]-dist[x]+c;add_edge(x,num,0);for (int p=y;p!=x;p=Fa[p]){int Dis=min(dist[p]-dist[x],sum[num]-(dist[p]-dist[x]));add_edge(p,num,Dis);flag[p]=(Dis==(dist[p]-dist[x]));}
}
void tarjan(int x,int father)
{dfn[x]=low[x]=++DFN,Fa[x]=father;for (auto V:e[x]){int v=V.to,c=V.c;if (!dfn[v]) dist[v]=dist[x]+c,tarjan(v,x),upmin(low[x],low[v]);else if (v!=father) upmin(low[x],dfn[v]);if (dfn[x]<low[v]) add_edge(x,v,c);}for (auto V:e[x]){int v=V.to,c=V.c;if (Fa[v]!=x&&dfn[v]>dfn[x]) solve(x,v,c);}
}
void dfs(int x,int father)
{dep[x]=dep[father]+1;for (int i=1;i<=Log[dep[x]];i++) fa[x][i]=fa[fa[x][i-1]][i-1],sm[x][i]=sm[fa[x][i-1]][i-1]+sm[x][i-1];for (auto v:E[x]){if (v.to==father) continue;fa[v.to][0]=x;sm[v.to][0]=v.c;dfs(v.to,x);}
}
int getans(int x,int y)
{int s=0;if (dep[x]<dep[y]) swap(x,y);for (int i=Log[dep[x]];i>=0;i--)if (dep[fa[x][i]]>=dep[y]) s+=sm[x][i],x=fa[x][i];
//  cout<<x<<" "<<y<<" "<<fa[x][0]<<" "<<s<<endl;if (x==y) return s;for (int i=Log[dep[x]];i>=0;i--)if (fa[x][i]!=fa[y][i]) s+=sm[x][i]+sm[y][i],x=fa[x][i],y=fa[y][i];//    cout<<x<<" "<<y<<" "<<fa[x][0]<<" "<<s<<endl;if (fa[x][0]<=n) return s+sm[x][0]+sm[y][0];int Dis;if (flag[x]^flag[y]) Dis=sm[x][0]+sm[y][0];else Dis=abs(sm[x][0]-sm[y][0]);return s+min(Dis,sum[fa[x][0]]-Dis);
}
int main()
{n=read(),m=read(),Case=read(),num=n;for (int i=1;i<=m;i++){int u=read(),v=read(),c=read();e[u].PB(((enode){v,c}));e[v].PB(((enode){u,c}));}tarjan(1,0);dep[0]=-1,Log[1]=0;for (int i=2;i<=num;i++) Log[i]=Log[i>>1]+1;dfs(1,0);
//  for (int i=1;i<=num;i++) cout<<fa[i][0]<<" "<<sm[i][0]<<" "<<fa[i][1]<<" "<<sm[i][1]<<endl;while (Case--){int x=read(),y=read();printf("%d\n",getans(x,y));}return 0;
}
/*
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 75
6
*/

bzoj#2125. 最短路相关推荐

  1. 圆方树(bzoj 2125: 最短路)

    2125: 最短路 Time Limit: 1 Sec  Memory Limit: 259 MB Submit: 1873  Solved: 754 [Submit][Status][Discuss ...

  2. 【刷题】BZOJ 2125 最短路

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

  3. BZOJ 2125 最短路 仙人掌最短路

    为了证明我还活着所以我发了篇博客_ (:з」∠) _ 题意: 给定一张仙人掌图,n<=10000,多次询问两点间最短路. Q<=10000. 解析: 首先如果这是一棵树的话,那么我们只需要 ...

  4. bzoj 2125: 最短路 CH6402 Freda的传呼机

    题意 给你一颗仙人掌,每一次问两点间的路径 题解 很少做仙人掌的题啊 我们一个方法,把仙人掌变为树 我们依然定义,1为根 我们考虑每一个环,我们找他最接近1的节点为父亲,成为顶,别的所有节点都连向他 ...

  5. bzoj 3040: 最短路(road)(堆优化dijkstra)

    3040: 最短路(road) Time Limit: 60 Sec  Memory Limit: 200 MB Submit: 2811  Solved: 933 [Submit][Status][ ...

  6. 2125: 最短路/3047: Freda的传呼机

    题目链接 题目大意:静态仙人掌最短路 题解:丢链接跑-- 我的收获:233333 //From popoqqq #include <map> #include <vector> ...

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

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

  8. 一句话题解(20170801~20170125)

    8.1 bzoj 4720 noip2016 换教室 floyd预处理+期望(薛定谔的猫) bzoj 4318 OSU! 三次函数期望值 从一次.二次推得 8.2 bzoj 1076 状压+期望DP ...

  9. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

最新文章

  1. SpringBoot+AntV实现饼状图中的花瓣图
  2. STM32 LED灯的另一种写法
  3. 【学习笔记】java核心技术学习笔记整理
  4. 蚂蚁资深技术专家王旭:开源项目是如何让这个世界更安全的?
  5. 复杂结构体的存取器 [C宏——智者的利刃,愚者的恶梦]
  6. 精彩编码 【进制转换】
  7. Java中 intValue,parseInt,Valueof 这三个关键字的区别
  8. java孢子进化_孢子进化论游戏
  9. ubuntu14.04 server 安装docker
  10. ABB码垛算法程序与设计接口参考案例
  11. 传智播客风清扬视频------异常简述
  12. android多个微信支付,想用快速开关一键收付款?Android 版微信没适配但你可以自己做...
  13. 独上高楼 望尽天涯路
  14. JavaWeb---HTTP与Request
  15. python爬虫学习 之 定向爬取 淘宝商品价格
  16. codeforces Intel Code Challenge Final Round (div.1 + div.2 combined)
  17. 阿里云李飞飞:帮1000家企业“去O”,完成10000套传统数据仓库上云
  18. 两场直播丨易鲸捷SQL编译器、达梦DM8数据库体系结构
  19. 快速获取颜色的RGB或十六进制码(取色技巧)
  20. mybatis尚硅谷跟学笔记

热门文章

  1. 杠杆原理的形象演示,你都懂了吗?
  2. 爱因斯坦为什么不是普通人?看他怎么喝茶就明白了,差距太明显了!没法比.......
  3. 多重信号辅助音频分离,让你在嘈杂环境也能指哪听哪儿
  4. android什么是回调,Android中的回调是什么?
  5. python为何排名越来越前_为何python现在越来越多的人在用了?
  6. mysql binlog oplog_mongodb 学习之oplog
  7. 设计模式在项目中的应用案例_设计模式在项目中的应用(初学者版)
  8. jpi多表联查_数据库两表联查、多表联查,多重联查
  9. python类的参数加self_python类参数self使用示例
  10. 数字调制系统工作原理_空间光调制器工作原理是什么 空间光调制器工作原理...