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
题面 怎么是权限题啊 题解 有一次考过, 但是不记得了 如果每个点都是加油站的话, 这道题就是货车运输 考虑如何转化 我们可以设
随机推荐
- 关于CoreData的一个工具Mogenerator的使用
最近看到用CoreData时使用的工具Mogenerator,发现网上介绍其具体使用的不多,特此简单整理一下, 关于CoreData这里就不具体说了,使用就用MagicalRecord,用起来真是太方 ...
- 使用R语言 SDK调取tushare数据
安装Tushare 打开RStudio,在控制台输入命令: > install.packages('Tushare') Tushare的R包需要依赖httr.tidyverse.forecast ...
- OpenCV3 VideoCapture buffer
在ubuntu16.04下写关于opencv的工程,在调用摄像头时发现VideoCapture有5帧的buffer,所以采用5个capture>>mat来处理. if (FlagConti ...
- GNU 交叉工具链的介绍与使用
常用工具介绍 名称 归属 作用 armlinuxas binutils 编译 ARM 汇编程序 armlinuxar binutils 把多个.o 合并成一个.o 或静态库(.a) arml ...
- gcc 4步编译过程
一. gcc编译过程 1. 预处理: 主要进行宏替换以及头文件的展开 gcc -E *.c -o *.i 2. 编译::编译生成汇编文件,会检查语法错误 gcc -S *.i ...
- django 项目分析
项目要点 一.功能制定 1.用户功能 #.登陆 #.权限组功能 2.数据展示功能 #.列表展示 #.详细信息展示 #.图标展示 3.资源管理功能 #远程管理 #对远程服务器上的进程具有 #开启 #关闭 ...
- 同步图计算实现最短路径Dijkstra算法
同上篇讲述pageRank一样,考虑一个顶点V. 根据顶点算法通常步骤1) 接收上个超步发出的入邻居的消息2) 计算当前顶点的值3) 向出邻居发消息 1.接收入邻居的消息 2.求入邻居的最小值,加上顶 ...
- Python连接数据库流行用到的第三方库
Python连接数据库流行用到的第三方库: mysqldb:只支持Python2.x mysqlclient : mysqldb的衍生版本,完全兼容mysqldb,同时支持Python3.x,安装较复 ...
- leetcode-216-组合总和③
题目描述: 方法一:回溯 class Solution: def combinationSum3(self, k: int, n: int) -> List[List[int]]: res = ...
- SQL Server - SQL Server/ bcp 工具如何通信
问题-BCP通讯 ref: https://stackoverflow.com/questions/40664708/bcp-cannot-connect-to-aws-sql-server-but- ...