当前位置:网站首页>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,那么从这个源点跑最短路只需要一次即可。
很妙!
边栏推荐
- 600MHz频段来了,它会是新的黄金频段吗?
- 数据库扩容也可以如此丝滑,MySQL千亿级数据生产环境扩容实战
- Mvc、Mvp和Mvvm
- typescript48-函数之间的类型兼容性
- 第1章:初识数据库与MySQL----MySQL安装
- Google Earth Engine - Calculates the effective width of rivers using publicly available river data
- Web3 安全风险令人生畏?应该如何应对?
- DataBinding下的RecycleView适配器Adapter基类
- 共享新能源充电桩充电站建设需要些什么流程及资料?
- typescript53-泛型约束
猜你喜欢

js函数防抖和函数节流及其使用场景

114. How to find the cause of Fiori Launchpad routing error by single-step debugging

c语言分层理解(c语言操作符)

typescript57-数组泛型接口

Nanoprobes丨Nanogold-抗体和链霉亲和素偶联物

【面经】被虐了之后,我翻烂了equals源码,总结如下

The 600MHz band is here, will it be the new golden band?

因为一次bug的教训,我决定手撕Nacos源码(先撕客户端源码)

Talking about the future development direction of my country's industrial parks

Shell编程之循环语句(for、while)
随机推荐
手撕Gateway源码,今日撕工作流程、负载均衡源码
What warehouse management problems can WMS warehouse management system solve in the electronics industry?
电子制造企业部署WMS仓储管理系统的好处是什么
因为一次bug的教训,我决定手撕Nacos源码(先撕客户端源码)
typescript54 - generic constraints
c语言分层理解(c语言指针(上))
typescript58 - generic classes
pcl点云数据 转化为 Eigen::Map
字符串变形
【正则表达式】笔记
typescript54-泛型约束
Apache DolphinScheduler新一代分布式工作流任务调度平台实战-中
共享新能源充电桩充电站建设需要些什么流程及资料?
BGP实验(含MPLS)
Nanoprobes丨Nanogold-抗体和链霉亲和素偶联物
ES6高级-迭代器与生成器的用法
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化
c语言分层理解(c语言操作符)
【超详细】手把手教你搭建MongoDB集群搭建
WMS仓储管理系统能解决电子行业哪些仓库管理问题