bzoj4144 Petrol
题意:给你一张n个点m条边的带权无向图。其中由s个点是加油站。询问从x加油站到y加油站,油箱容量<=b,能否走到?
n,m,q,s<=20W,b<=2e9。
标程:
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
int read()
{
int x=;char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (''<=ch&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
return x;
}
const int N=;
const int inf=0x3f3f3f3f;
struct node{int to,next,w;}num[N*];
struct _node{int i;ll dis;_node(int A,ll B){i=A;dis=B;}};
struct Node{int u,v,id;ll dis;Node(){}; Node(int A,int B,ll C,int D){u=A;v=B;dis=C;id=D;}}a[N],e[N];
struct cmp{
bool operator () (const _node &A,const _node &B)
{return A.dis>B.dis;}
};
priority_queue<_node,vector<_node>,cmp>q;
int cnt,S,fa[N],u,v,w,n,s,m,head[N],vis[N],f[N],Q,ans[N],tot;
ll dis[N],b;
void add(int x,int y,int w)
{num[++cnt].to=y;num[cnt].next=head[x];num[cnt].w=w;head[x]=cnt;}
int find(int x) {return x==f[x]?x:f[x]=find(f[x]);}
bool operator < (const Node &A,const Node &B){return A.dis<B.dis;}
void dijk()
{
while (!q.empty())
{
_node now=q.top();q.pop();
if (vis[now.i]) continue;vis[now.i]=;
for (int i=head[now.i];i;i=num[i].next)
if (dis[num[i].to]>dis[now.i]+num[i].w)
{
dis[num[i].to]=dis[now.i]+num[i].w;q.push(_node(num[i].to,dis[num[i].to]));
fa[num[i].to]=fa[now.i];
}
}
}
void init()
{
for (int i=;i<=n;i++)
for (int j=head[i];j;j=num[j].next)
if (fa[i]!=fa[num[j].to]&&fa[i]<fa[num[j].to]) e[++tot]=Node(fa[i],fa[num[j].to],dis[i]+dis[num[j].to]+num[j].w,tot);
}
void mst()
{
int head=;
for (int i=;i<=n;i++) f[i]=i;
for (int i=;i<=Q;i++)
{
while (head<=tot&&e[head].dis<=a[i].dis)
{
int x=e[head].u,y=e[head].v;
if (find(x)!=find(y)) f[find(x)]=find(y);
head++;
}
if (find(a[i].u)!=find(a[i].v)) ans[a[i].id]=;else ans[a[i].id]=;
}
}
int main()
{
n=read();s=read();m=read();
memset(dis,inf,sizeof(dis));
for (int i=;i<=s;i++) S=read(),dis[S]=,q.push(_node(S,)),fa[S]=S;
for (int i=;i<=m;i++) u=read(),v=read(),w=read(),add(u,v,w),add(v,u,w);
dijk();init();
Q=read();
for (int i=;i<=Q;i++) a[i].u=read(),a[i].v=read(),a[i].dis=read(),a[i].id=i;
sort(a+,a+Q+);sort(e+,e+tot+);
mst();
for (int i=;i<=Q;i++) puts(ans[i]?"TAK":"NIE");
return ;
}
题解:并查集+技巧
要走到肯定是瞄准了加油站走。而且每次如果能走,往最近的加油站走答案一定不会变劣(你也可以走回来)。
那么就有一种高超的建图方法:
1.跑多源最短路,找到每个点离它最近的加油站,算出距离。
2.对于原图边(u,v),如果nearest[u]!=nearest[v],那么连边nearest[u]-nearest[v],边权为dist(u,nearest[u])+dist(v,nearest[v])+dist(u,v)。
这样离u,v最近的加油站就有经过(u,v)的一条路径了,但是不一定这样的dist(nearest[u],nearest[v])就是实际最短路,然而如果不是实际最短路,一定有另一个加油站k,离这边一个加油站更近,而且这样nearest[u]和nearest[v]一定通过另外几个加油站连通,实际走的策略也应该是经过另外几个加油站的。
离线掉询问按b从小到大排序,也按照b的顺序加入边,用并查集维护连通性。查询时,起点终点在同一个块中则可行。O((q+n)a)。
需要在线的话就构造出最小生成树,倍增/树剖找链上最大值。
bzoj4144 Petrol的更多相关文章
- 题解 [BZOJ4144] Petrol
题目描述 有一张 n 个点 m 条边的无向图,其中有 s 个点上有加油站.有 Q 次询问(a,b,c), 问能否开一辆油箱容积为 c 的车从 a 走到 b.(a,b均为加油站) 输入格式 第一 ...
- 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树
[BZOJ4144][AMPPZ2014]Petrol Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油 ...
- bzoj4144【AMPPZ2014】Petrol
题解: 首先注意到起点和终点都是加油站; 假设中途经过某个非加油站的点u,u连到v,离u最近的加油站是x,那么从u到x加油后回到u,再到v一定不比直接从u到v差: 因 ...
- BZOJ4144 [AMPPZ2014]Petrol 【最短路 + 最小生成树】
题目链接 BZOJ4144 题解 这题好妙啊,,orz 假设我们在一个非加油站点,那么我们一定是从加油站过来的,我们剩余的油至少要减去这段距离 如果我们在一个非加油站点,如果我们到达不了任意加油站点, ...
- 【BZOJ4144】[AMPPZ2014]Petrol(最短路+最小生成树+并查集)
Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油站可以补满. q次询问,每次给出x,y,b,表示出发点是 ...
- [BZOJ4144][AMPPZ2014]Petrol[多源最短路+MST]
题意 题目链接 分析 假设在 \(a \rightarrow b\) 的最短路径中出现了一个点 \(x\) 满足到 \(x\) 最近的点是 \(c\) ,那么我们完全可以从 \(a\) 直接走到 \( ...
- BZOJ4144: [AMPPZ2014]Petrol(最短路 最小生成树)
题意 题目链接 Sol 做的时候忘记写题解了 可以参考这位大爷 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- bzoj4144 [AMPPZ2014]Petrol
link 题意: 给一个n个点m条边的带权无向图,其中k个点是加油站,每个加油站可以加满油,但不能超过车的油量上限.有q个询问,每次给出x,y,b,保证x,y都是加油站,问一辆油量上限为b的车从x出发 ...
- [题解] [BZOJ4144] 「AMPPZ2014」Petrol
题面 怎么是权限题啊 题解 有一次考过, 但是不记得了 如果每个点都是加油站的话, 这道题就是货车运输 考虑如何转化 我们可以设
随机推荐
- C++输入cin详解
输入原理: 程序的输入都建有一个缓冲区,即输入缓冲区.一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据.正因为cin函数是直接从缓冲区取数据 ...
- C++之string
一.常用操作 二.用“+”连接字符串的注意事项
- Openstack Nova 源码分析 — RPC 远程调用过程
目录 目录 Nova Project Services Project 的程序入口 setuppy Nova中RPC远程过程调用 nova-compute RPC API的实现 novacompute ...
- NetBeans简介和简单使用
1.什么是NetBeans? NetBeans IDE:可以使开发人员利用Java平台能够快速创建Web.企业.桌面以及移动的应用程序: 支持语言:PHP.Ruby.JavaScript.Groovy ...
- log4j架构
Log4j API设计为分层结构,其中每一层提供了不同的对象,对象执行不同的任务.这使得设计灵活,根据将来需要来扩展. 有两种类型可用在Log4j的框架对象. 核心对象: 框架的强制对象和框架的使用. ...
- Balking Pattern不需要就不用做
word自动保存功能,如果文档被修改了,后台线程每隔一段时间会自动执行保存功能,但是如果用户在自动保存之前用Ctrl+S手动保存呢?自动保存还会执行吗?答案是不会,因为这个操作时不需要重复做的. pu ...
- JS对象 向下取整floor() floor() 方法可对一个数进行向下取整。 语法: Math.floor(x)
向下取整floor() floor() 方法可对一个数进行向下取整. 语法: Math.floor(x) 参数说明: 注意:返回的是小于或等于x,并且与 x 最接近的整数. 我们将在不同的数字上使用 ...
- Centos6 安装完之后,没有网络
Virtualbox安装的centos 6.10的虚拟机,安装时,网络是NAT网络,安装完之后,将网络改为桥接网卡,启动虚拟机之后,使用 ifconfig 命令查看没有到eth0的信息,只有127.0 ...
- 查看收到的邮件的来源ip以及包信息
有时我们需要知道收到的邮件是从哪台服务器发送过来的,或者想知道该邮件的报文头是怎样的.以下以网易邮箱为例介绍如果抓取这些信息. 首先我们需要知道网易邮箱的访问服务器(拉协议),由于SMTP是推的协议, ...
- SpringBoot防止重复请求,重复表单提交超级简单的注解实现
1. 注解接口 /** * @description 防止表单重复提交注解 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHO ...