bzoj#2125. 最短路

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
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315812.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dapper的正确使用姿势

本文demo适用于MySQL优点高性能、易排查、易运维、灵活可控缺点和EF相比&#xff0c;手写sql当修改表结构不易发现bug。习惯了EF后再来使用Dapper&#xff0c;会很难适应那种没有了强类型的安全感。不过可以用单元测和心细来避免。问题&#xff1a;IDbConnection需不需要手动Op…

P4064 [JXOI2017]加法

P4064 [JXOI2017]加法 题意&#xff1a; 题解&#xff1a; 要求找最小值尽可能大&#xff0c;很明显二分&#xff0c;现在是如何判断二分出来的答案的正确性 对于一个二分出来的答案mid&#xff0c;要求对k个区间进行操作后&#xff0c;最小值大于mid&#xff0c;我们可以这…

[NewLife.XCode]百亿级性能

NewLife.XCode是一个有10多年历史的开源数据中间件&#xff0c;支持nfx/netcore&#xff0c;由新生命团队(2002~2019)开发完成并维护至今&#xff0c;以下简称XCode。整个系列教程会大量结合示例代码和运行日志来进行深入分析&#xff0c;蕴含多年开发经验于其中&#xff0c;代…

LuoguP4606 [SDOI2018]战略游戏

LuoguP4606 [SDOI2018]战略游戏 题目描述 题目描述 省选临近&#xff0c;放飞自我的小 QQ 无心刷题&#xff0c;于是怂恿小 CC 和他一起颓废&#xff0c;玩起了一款战略游戏。 这款战略游戏的地图由 nn 个城市以及 mm 条连接这些城市的双向道路构成&#xff0c;并且从任意一个…

Jozky 刷题目录

文章目录本目录参考OI-Wiki还未解决专区算法基础枚举模拟递归&分治贪心排序前缀和&差分二分倍增构造搜索DFS && BFS双向搜索启发式搜索A*迭代加深搜索IDA*回溯法Dancing Links搜索优化&#xff08;剪枝&#xff09;动态规划普通dp背包dp区间dpDAG上的dp树形dp状…

Web API 速率限制(一)

导读当您API有大量消费者或者请求量猛增到影响程序可用性的时候&#xff0c;您可能需要对API进行速率限制。所以对API进行限速的在于&#xff1a;在增加可靠性和可用性的同时来保护基础架构&#xff0c;你不希望某个恶意的API消费者或者差劲的API客户端开发者通过Dos攻击把你的…

训练赛合集

带 # 的为未补 带△的为未补完 带※的为补不动 比赛合集 牛客 △2021年度训练联盟热身训练赛第一场 Codeforces Codeforces Round #694 Div. 2 △Codeforces Round #695 (Div. 2) Codeforces Round #696 (Div. 2) △CodeCraft-21 and Codeforces Round #711 (Div. 2) Codef…

构建简单的微服务架构

前言 本篇仅作引导&#xff0c;内容较多&#xff0c;如果阅读不方便&#xff0c;可以使用电脑打开我们的文档官网进行阅读。如下图所示&#xff1a;文档官网地址&#xff1a;docs.xin-lai.com目录总体介绍微服务架构的好处 微服务架构的不足&#xff08;这个时候…

[AGC026D]Histogram Coloring

[AGC026D]Histogram Coloring 题目描述 题面 题意大概是有一个nnn列网格图&#xff0c;给定一个长度为nnn的序列hih_ihi​&#xff0c;第iii列只保留这一列最下面的hih_ihi​个格子。 现在需要给这些保留下来的格子染成红色或蓝色&#xff0c;满足每一个完整的222222正方形…

每日训练赛

文章目录说明2021.9.242021.9.252021.9.262021.9.272021.9.282021.9.292021.9.302021.10.12021.10.22021.10.32021.10.42021.10.52021.10.62021.10.72021.10.82021.10.92021.10.132021.10.152021.10.162021.10.212021.10.222021.10.242021.10.252021.10.262021.10.29说明 记录…

读《代码整洁之道》

什么是整洁代码代码的质量非常重要&#xff0c;糟糕的代码有可能会毁了一个公司。对于一个很注重代码质量的人来说呆在一个只关注交付而不关注代码质量的公司是很痛苦的。什么是整洁的代码&#xff0c;不同的人又不同的定义。我认为整洁的代码应该是符合所使用语言代码规范的&a…

[ZJOI2016]小星星

[ZJOI2016]小星星 题目描述 luogu题面 给定一个n个点的树和n个点m条边的无向图&#xff0c;求将树嵌入图的方案数。 其中 n≤17,m≤n∗(n−1)2n \leq 17,m \leq \frac{n*(n-1)}{2}n≤17,m≤2n∗(n−1)​。 Solution 点数很少&#xff0c;考虑状压DP。 令f[i][j][k]f[i][j]…

在 DotNetty 中实现同步请求

一、背景DotNetty 本身是一个优秀的网络通讯框架&#xff0c;不过它是基于异步事件驱动来处理另一端的响应&#xff0c;需要在单独的 Handler 去处理相应的返回结果。而在我们的实际使用当中&#xff0c;尤其是 客户端程序 基本都是 请求-响应 模型&#xff0c;在发送了数据时候…

BZOJ#3252. 攻略

BZOJ#3252. 攻略 题目描述 Solution 有一个显然的 贪心&#xff0c;每次选取一个到根的点权和最大的点xxx&#xff0c;将答案加上xxx到根的路径的点权和&#xff0c;并将xxx到根的路径上的点的权值清零。 可以使用DFS序线段树维护。 但完全没有这么麻烦。 容易发现每一次选…

ASP.NET Core 中间件

1.前言中间件&#xff08;middleware&#xff09;是一种装配到应用管道以处理请求和响应的组件。每个组件&#xff1a;●可选择是否将请求传递到管道中的下一个组件。●可在管道中的下一个组件前后执行工作。请求委托&#xff08;request delegates&#xff09;用于建立请求管道…

P3899 [湖南集训]谈笑风生

P3899 [湖南集训]谈笑风生 题目描述 Solution 我们考虑离线询问&#xff0c;将询问放在相对应的子树ppp中计算答案。 显然a,b,ca,b,ca,b,c的位置关系有两种情况&#xff1a; bbb是aaa的祖先&#xff0c;ccc是aaa的子孙。aaa是bbb的祖先&#xff0c;ccc是bbb的子孙。 第一种…

.Net Core实现的文档数据库RavenDb

说到文档数据库&#xff0c;大家能想到很多&#xff0c;MongoDb,coudDb。如果只是文档的话&#xff0c;甚至可以使用对象存储&#xff0c;阿里的oss&#xff0c;腾讯cos。但是这里小编选择这RavenDb&#xff0c;原因是对象存储下行太贵了(来自穷逼的绝望)。MongoDb据说非常占用…

bzoj4543. [POI2014]Hotel加强版

bzoj4543. [POI2014]Hotel加强版 题面描述 Solution 先看n≤5e3n \leq 5e3n≤5e3怎么做。 考虑树形dpdpdp。 设f[i][j]f[i][j]f[i][j]表示以iii为根的子树中&#xff0c;深度为jjj的结点个数。 设g[i][j]g[i][j]g[i][j]表示以iii为根的子树中的二元组(x,y)(x,y)(x,y)数量&a…

Web Template Studio 发布!在 VS Code 中轻松创建 Web 应用

作为一个 Web 应用开发者&#xff0c;Scaffolding Tool&#xff08;脚手架工具&#xff09;一定是在创建项目时的重要工具。许多开发者会习惯于使用基于 CLI 的脚手架工具来创建 Web 应用&#xff0c;也有许多开发者喜欢使用类似于 VS IDE 的基于 UI 的 Wizard 向导。近期&…

AGC022E - Median Replace

AGC022E - Median Replace 题面描述 Solution 直接构造自动机&#xff0c;模拟每次在末尾加一个字符的当前状态的方案数f[state]f[state]f[state]&#xff0c;状态很少&#xff0c;直接打表转移即可。 时间复杂度O(n)O(n)O(n)。 #include <vector> #include <lis…