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
题面 怎么是权限题啊 题解 有一次考过, 但是不记得了 如果每个点都是加油站的话, 这道题就是货车运输 考虑如何转化 我们可以设
随机推荐
- .Net Core 部署之一 《CentOS 从GitHub/Gitee 等源代码网站部署Web网站》
先看下楼主从某阿打折购买的渣渣服务器 lsb_release -a 一.安装dotnet-SDK 注册微软的服务 sudo rpm -Uvh https://packages.microsoft.co ...
- 如何优雅的使用Objects.requireNonNull(T obj, String message)定制你的NPE异常
IDEA中习惯跟踪源码实现逻辑,多次碰到Objects.requireNonNull(T obj)这个方法,改方法主要用于提早判断对象是否为空,以便更早的抛出NPE 平时小组开发中强调程序健壮性,不允 ...
- scrapy的使用-LinkExtractor
背景: 在爬取网站信息是需要获取特定标签下的某些内容,就需要获取这些标签下的链接,如果获取每一个,在通过这个获取它下面的信息,这样效率会很低,时间复杂度O(n^2),但如果先获取链接,再获取内容,则时 ...
- WinDbg神断点
https://blogs.msdn.microsoft.com/alejacma/2007/10/31/cryptoapi-tracer-script/ 我得多少年才能学会这种写法.
- 可读性 vs 效率
哪个重要. 应用层代码来说,实际上说任意一个重要都不为过, 但是到了内核里面之后,哪个重要. 肯定是效率阿,内核跑得慢,上面还有得玩么.
- maven中报错Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0
在检索完工程后报错Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0. 由于oracle的ojdbc收费,所以在maven项目导入时没有ojdbc14 ...
- C++ static静态成员变量在类中仅仅是声明
今天写代码时看到: 图1的3个静态成员变量在类中仅仅是声明,没有定义以及分配内存:必须在类外,图中就是cpp中,定义分配内存,才能使用
- SQL语句转换成MapReduce的基本原理
- 新知道一个 端对端加密 Signal protocol
看 socketio Sponsors 列表中的小蓝鸟,发现网站中有使用 x-jquery-tmpl [翻译]WhatsApp 加密概述(技术白皮书) 知道一个叫 Signal 协议 的端对端加密 端 ...
- [JZOJ3691] 【CF414E】Mashmokh's Designed tree
题目 题目大意 给你一棵树,接下来对这棵树进行三种操作: 1.询问两点之间的距离. 2.让某个点变为它原来的第\(h\)个祖先的最后一个儿子. 3.求\(dfs\)序中最后一个深度为\(k\)的点. ...