当前位置:网站首页>Slipper —— 虚点,最短路
Slipper —— 虚点,最短路
2022-08-04 00:56:00 【小酒窝.】
题意
给定根节点为 1,节点数为 n n n 的一棵树,n-1 条边有边权 w i w_i wi。
如果两个点 u , v u, v u,v 深度之差为 k ( ∣ d e p u − d e p v ∣ = k ) k\ (|dep_u−dep_v|=k) k (∣depu−depv∣=k) ,可以直接相互到达,花费为 p p p。
给定起点和终点,问从起点到终点的最小花费。
2 ≤ n ≤ 1 0 6 , 1 ≤ u , v ≤ n , 1 ≤ w ≤ 1 0 6 . 2≤n≤10^6,\ 1≤u,v≤n,\ 1≤w≤10^6. 2≤n≤106, 1≤u,v≤n, 1≤w≤106.
1 ≤ k ≤ m a x u ⊆ V ( d e p u ) , 0 ≤ p ≤ 1 0 6 . 1≤k≤max_u⊆V(dep_u),\ 0≤p≤10^6. 1≤k≤maxu⊆V(depu), 0≤p≤106.
思路
两层节点之间花费 p 直接到达,那么就可以连边。
但是如果直接连边的话,假设两层点数分别为 n, m,那么连边数为 n*m,边数很多。
是否可以少连边呢?
在两层之间建一个虚点,上层所有节点向虚点连一条由向边,边权为 p;从虚点向下层所有节点连一条有向边,边权为 0。连边数 n+m。
注意是有向边!
那么这样上层任一节点到下层任一节点的花费仍是 p,但是少建很多边!
这题就是这个思路,能够直接到达的两层之间都建立一个虚点,两层节点向这个虚点连边,然后就可以直接跑最短路了。
需要注意,输入数量到达 5e6,要换scanf,最好用快读。
Code
#include<bits/stdc++.h>
using namespace std;
#define Ios ios::sync_with_stdio(false),cin.tie(0)
#define int long long
#define PII pair<int,int>
#define pb push_back
#define fi first
#define se second
#define endl '\n'
static char buf[100000],*pa=buf,*pd=buf;
#define gc pa==pd&&(pd=(pa=buf)+fread(buf,1,100000,stdin),pa==pd)?EOF:*pa++
inline int read()
{
register int x(0);register char c(gc);
while(c<'0'||c>'9')c=gc;
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=gc;
return x;
}
const int N = 1000010, mod = 1e9+7;
int T, n, m;
int a[N];
vector<PII> e[N*2];
int k, p, st, en;
int dep[N];
vector<int> v[N];
int maxdep;
int dist[N*2], f[N*2];
void bfs()
{
for(int i=1;i<=n;i++) dep[i] = 0;
dep[1] = 1;
queue<int> que;
que.push(1);
v[1].push_back(1);
while(que.size())
{
int x = que.front(); que.pop();
for(PII it : e[x])
{
int tx = it.fi;
if(dep[tx]) continue;
dep[tx] = dep[x] + 1;
v[dep[tx]].push_back(tx);
maxdep = max(maxdep, dep[tx]); //可以维护最大深度,以减少后面的初始化和建边
que.push(tx);
}
}
}
int dij()
{
for(int i=1;i<=2*n;i++) dist[i] = 1e18, f[i] = 0;
dist[st] = 0;
priority_queue<PII, vector<PII>, greater<PII> > que;
que.push({
0, st});
while(que.size())
{
int x = que.top().se; que.pop();
if(f[x]) continue;
f[x] = 1;
if(x == en) return dist[x];
for(auto it : e[x])
{
int tx = it.fi, dis = it.se;
if(dist[tx] > dist[x] + dis)
dist[tx] = dist[x] + dis, que.push({
dist[tx], tx});
}
}
return -1;
}
void init()
{
for(int i=1;i<=n;i++) v[i].clear();
for(int i=1;i<=2*n;i++) e[i].clear();
maxdep = 1;
}
signed main(){
T = read();
while(T--)
{
n = read();
init();
for(int i=1;i<n;i++)
{
int x, y, z;
x = read(), y = read(), z = read();
e[x].push_back({
y, z});
e[y].push_back({
x, z});
}
k = read(), p = read();
st = read(), en = read();
bfs();
for(int i=1;i<=n;i++)
{
int tx = i + k;
if(tx > maxdep) break; //大于最大深度就不用管了
for(int t : v[i]) e[t].push_back({
n+i, p});
for(int t : v[tx]) e[n+i].push_back({
t, 0});
}
printf("%lld\n", dij());
}
return 0;
}
经验
建立虚点,很妙的做法。
还看到一个应用:
如果有若干个起点,若干个终点,求任一起点到任一终点的最短距离。
这时如果朴素做的话就要跑 n 次最短路,但是可以建一个虚拟源点,向所有起点连边,权值为 0,那么从这个源点跑最短路只需要一次即可。
很妙!
边栏推荐
- Jmeter cross-platform operation CSV files
- Read FastDFS in one article
- Analysis of usage scenarios of mutex, read-write lock, spin lock, and atomic operation instructions xaddl and cmpxchg
- Justin Sun: Web3.0 and the Metaverse will assist mankind to enter the online world more comprehensively
- 字符串变形
- 哎,又跟HR在小群吵了一架!
- MPLS Comprehensive Experiment
- VR全景拍摄线上展馆,3D全景带你沉浸体验
- WMS仓储管理系统能解决电子行业哪些仓库管理问题
- 取模运算(MOD)
猜你喜欢
网络带宽监控,带宽监控工具哪个好
LeetCode third topic (the Longest Substring Without Repeating Characters) trilogy # 3: two optimization
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化
typescript55 - generic constraints
手撕Nacos源码,今日撕服务端源码
电子组装行业对MES管理系统的需求分析
谁说程序员不懂浪漫,表白代码来啦~
LYVE1抗体丨Relia Tech LYVE1抗体解决方案
中原银行实时风控体系建设实践
咱们500万条数据测试一下,如何合理使用索引加速?
随机推荐
机器学习——库
MPLS Comprehensive Experiment
Sqlnet. Ora file with the connection of authentication test
win10+cuda11.7+pytorch1.12.0 installation
jmeter distributed stress test
typescript48 - type compatibility between functions
typescript50 - type specification between cross types and interfaces
Shell编程之循环语句(for、while)
【正则表达式】笔记
The Beijing E-sports Metaverse Forum was successfully held
教你如何定位不合理的SQL?并优化之
vxe-table 从页面批量删除数据 (不动数据库里的数据)
c语言分层理解(c语言操作符)
【虚拟化生态平台】虚拟化平台esxi挂载USB硬盘
越来越火的图数据库到底能做什么?
全面讲解 Handler机制原理解析 (小白必看)
typescript58-泛型类
114. 如何通过单步调试的方式找到引起 Fiori Launchpad 路由错误的原因
typescript57-数组泛型接口
dynamic memory two