CF1253F Cheap Robot(神奇思路,图论,最短路,最小生成树/Kruskal 重构树/并查集)
神仙题。
先考虑平方级别的暴力怎么做。
明显答案有单调性,先二分 \(c\)。
先最短路预处理 \(dis_u\) 表示 \(u\) 到离它最近的充电站的距离(一开始把 \(1\) 到 \(k\) 全部丢到优先队列里就行了)。
考虑当前站在 \(u\) 点上时,剩余的电量是 \(x\)。注意到由于起点是充电站,就一定有 \(x\le c-dis_u\)(考虑最后一个走到的充电站沿最短路走到这)
如果 \(x<dis_u\),因为终点是充电站,肯定不可能再到终点。
否则就可以走到最近的充电站再回来,\(x\) 就可以变成 \(c-dis_u\)。前面也推过不可能变得更大。
于是就可以直接 DFS 了。
void dfs(int u,ll x){
    if(x<0) return;
    vis1[u]=true;    //走到过这个点
    if(x<dis[u]) return;
    vis2[u]=true;    //走到过这个点并且电量大于dis[u]
    for(int i=head[u];i;i=nxt[i]){
        int v=to[i];
        if(vis2[v]) return;
        dfs(v,c-dis[u]-w[i]);
    }
}
怎么搞快点?
由于走到 \(u\) 时要 \(x\ge dis_u\) 才有用,所以考虑我们会走一条边 \((u,v,w)\),当且仅当 \(c-dis_u-w\ge dis_v\),即 \(dis_u+dis_v+w\le c\)。
那么问题变成求一条从 \(a\) 到 \(b\) 的路径使得路径上每条边的 \(dis_u+dis_v+w\) 的最大值最小(明显是满足条件的最小的 \(c\))。
还不会?
右转 NOIP2013 货车运输。
如果用最小生成树或者 Kruskal 重构树,时间复杂度大概是 \(O((n+m)\log n+m\log m+m\log n+q\log n)\)。(最短路+给边排序+求树+LCA)
(顺便提个并查集的做法:询问离线下来,森林中每棵树的根记录这里面有哪些点。使用按秩合并,每个点至多被合并 \(\log\) 次。)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=600060;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
	char ch=getchar();ll x=0,f=0;
	while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
	return f?-x:x;
}
struct node{
	ll d;
	int id;
	bool operator<(const node &nd)const{return d>nd.d;}
};
struct edge{
	int u,v;
	ll w;
	bool operator<(const edge &e)const{return w<e.w;}
}e[maxn];
int n,m,k,q,el,head[maxn],to[maxn],nxt[maxn],w[maxn],u_fa[maxn];
int cnt,el2,head2[maxn],to2[maxn],nxt2[maxn],fa[maxn],sz[maxn],son[maxn],top[maxn],dep[maxn];
ll wnd[maxn],dis[maxn];
priority_queue<node> pq;
inline void add(int u,int v,int w_){
	to[++el]=v;nxt[el]=head[u];head[u]=el;w[el]=w_;
}
inline void add2(int u,int v){
	to2[++el2]=v;nxt2[el2]=head2[u];head2[u]=el2;
}
int getfa(int x){
	return x==u_fa[x]?x:u_fa[x]=getfa(u_fa[x]);
}
void dfs1(int u,int f){
	sz[u]=1;
	dep[u]=dep[fa[u]=f]+1;
	for(int i=head2[u];i;i=nxt2[i]){
		int v=to2[i];
		if(v==f) continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u]=v;
	}
}
void dfs2(int u,int topf){
	top[u]=topf;
	if(son[u]) dfs2(son[u],topf);
	for(int i=head2[u];i;i=nxt2[i]){
		int v=to2[i];
		if(v==fa[u] || v==son[u]) continue;
		dfs2(v,v);
	}
}
int lca(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=fa[top[u]];
	}
	return dep[u]<dep[v]?u:v;
}
int main(){
	n=read();m=read();k=read();q=read();
	FOR(i,1,m){
		int u=read(),v=read(),w=read();
		add(u,v,w);add(v,u,w);
		e[i]=(edge){u,v,w};
	}
	MEM(dis,0x3f);
	FOR(i,1,k) pq.push((node){dis[i]=0,i});
	while(!pq.empty()){
		ll d=pq.top().d;
		int u=pq.top().id;
		pq.pop();
		if(d!=dis[u]) continue;
		for(int i=head[u];i;i=nxt[i]){
			int v=to[i];
			if(dis[v]>d+w[i]) pq.push((node){dis[v]=d+w[i],v});
		}
	}
	FOR(i,1,m) e[i].w+=dis[e[i].u]+dis[e[i].v];
	sort(e+1,e+m+1);
	FOR(i,1,2*n) u_fa[i]=i;
	cnt=n;
	FOR(i,1,m){
		int u=e[i].u,v=e[i].v;
		ll w=e[i].w;
		u=getfa(u);v=getfa(v);
		if(u==v) continue;
		u_fa[u]=u_fa[v]=++cnt;
		wnd[cnt]=w;
		add2(cnt,u);add2(cnt,v);
	}
	dfs1(cnt,0);dfs2(cnt,cnt);
	while(q--){
		int u=read(),v=read();
		printf("%lld\n",wnd[lca(u,v)]);
	}
}
												
											CF1253F Cheap Robot(神奇思路,图论,最短路,最小生成树/Kruskal 重构树/并查集)的更多相关文章
- Luogu4768 NOI2018 归程 最短路、Kruskal重构树
		
传送门 题意:给出一个$N$个点.$M$条边的图,每条边有长度和海拔,$Q$组询问,每一次询问从$v$开始,经过海拔超过$p$的边所能到达的所有点中到点$1$的最短路的最小值,强制在线.$N \leq ...
 - 【BZOJ5415&UOJ393】归程(Kruskal重构树,最短路)
		
题意:From https://www.cnblogs.com/Memory-of-winter/p/11628351.html 思路:先从1开始跑一遍dijkstra,建出kruskal重构树之后每 ...
 - 【NOI2018】归程 题解(kruskal重构树+最短路)
		
题目链接 题目大意:给定一张$n$个点$m$条边的无向图.每条边有长度和海拔.有$Q$次询问,每次给定起点$v$和当天水位线$p$,每次终点都是$1$.人可以选择坐车或走路,车只能在海拔大于水位线的路 ...
 - bzoj3694: 最短路(树链剖分/并查集)
		
bzoj1576的帮我们跑好最短路版本23333(双倍经验!嘿嘿嘿 这题可以用树链剖分或并查集写.树链剖分非常显然,并查集的写法比较妙,涨了个姿势,原来并查集的路径压缩还能这么用... 首先对于不在最 ...
 - 图论(最短路&最小生成树)
		
图论 图的定义与概念 图的分类 图,根据点数和边数可分为三种:完全图,稠密图与稀疏图. 完全图,即\(m=n^2\)的图\((m\)为边数,\(n\)为点数\()\).如: 1 1 0 1 2 1 1 ...
 - loj2718 「NOI2018」归程[Kruskal重构树+最短路]
		
关于Kruskal重构树可以翻阅本人的最小生成树笔记. 这题明显裸的Kruskal重构树. 然后这题限制$\le p$的边不能走,实际上就是要满足走最小边权最大的瓶颈路,于是跑最大生成树,构建Krus ...
 - 洛谷P4768 [NOI2018]归程(可持久化并查集,最短路)
		
闲话 一个蒟蒻,在网络同步赛上进行了这样的表演-- T2组合计数不会,T3字符串数据结构不会,于是爆肝T1 一开始以为整个地图都有车,然后写了2h+的树套树,终于发现样例过不去 然后写可持久化并查集D ...
 - POJ 1182 食物链 [并查集 带权并查集 开拓思路]
		
传送门 P - 食物链 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit ...
 - P1197 [JSOI2008]星球大战[并查集+图论]
		
题目来源:洛谷 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球 ...
 
随机推荐
- mysql初始化/usr/local/mysql/bin/mysqld: error while loading shared libraries: libnuma.so.1: cannot open shared object file: No such file or directory
			
[root@test153 ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql - ...
 - packstack-ironic
			
安装openstack Pike版本, 其它版本安装方法类似. centos7.6 packstack目前对NetworkManager 还不支持,我们修改下配置: systemctl disable ...
 - mongodb使用_遍历列表中的元素,作为变量,循环修改mongodb中的字段
			
一.问题描述: 需要将工作界面上的一些已经离职的用户状态改为失效,并备注为离职 二.需要准备/拿到手的工具/条件/数据: 1.已离职人员名单(excel格式) 2.任意mongodb工具(笔者使用的是 ...
 - vue.set( target, key, value )     this.$set(对象获数组,要更改的具体数据,重新赋值)用法
			
调用方法:Vue.set( target, key, value ) target:要更改的数据源(可以是对象或者数组) key:要更改的具体数据 value :重新赋的值 具体用法js代码: //设 ...
 - C和C++常见误区以及问题整理
			
c和c++的关系 c是面向过程的语言,c++是在c的基础上扩展的面向对象的编程语言. c++具备c的所有功能,对c的库完全兼容. c++的标准在98年确定,在那之前已经有一些库大量使用. 新标准中,推 ...
 - Web安全测试学习笔记-DVWA-存储型XSS
			
XSS(Cross-Site Scripting)大致分为反射型和存储型两种,之前对XSS的认知仅停留在如果网站输入框没有屏蔽类似<script>alert('ok')</scrip ...
 - strlen函数 (求字符串长度函数)
			
strlen函数原型在<string.h>中 #include <stdio.h> #include <string.h> int main(){ char *p= ...
 - 【Java基础】Java中你必须知道的知识点
			
目录 Java中面向对象的基础知识 1. 什么是面向对象 2. 三大基本特征和五项基本原则 3. Java的平台无关性 4. 值传递和引用传递 5. 方法重载和重写 6. 基本数据类型 7. 包装类 ...
 - Spring Boot可执行Jar包运行原理
			
目录 1. 打可执行Jar包 2. 可执行Jar包内部结构 3. JarLauncher 4. 简单总结 5. 远程调试 Spring Boot有一个很方便的功能就是可以将应用打成可执行的Jar.那么 ...
 - React 从入门到进阶之路(一)
			
在开始 React 学习之前我们先进入官网 https://react.docschina.org/ 看看官方对 React 的解释:React 是用于构建用户界面的JavaScript 库.我们只需 ...