题意

题目链接

分析

  • 由于起点和终点都是加油站,所以我们可以把整个问题看成是从加油站到加油站。
  • 考虑一个暴力的做法,用最短路在 \(O(n^2\log n)\) 的时间内求出加油站两两之间的最短路。于是问题变成了最小瓶颈路。把所有询问离线跑最小生成树,判断连通性即可。
  • 考虑优化刚才的建边。假设 \(a,b,c\) 都是加油站。在 \(a \rightarrow b\) 的最短路径中出现了一个点 \(x\) 满足到 \(x\) 最近的点是 \(c\) ,那么我们完全可以从 \(a\) 直接走到 \(c\),而 \(c\) 又是当前最近的能够到达的加油站,所以这样走一定会更优。
  • 将加油站全部放入优先队列跑最短路,求出距离每个点最近的加油站 \({from}_x\) 和 \(x\) 到 \(from_x\) 的距离 \(dis_x\) 。
  • 枚举每条边如果两端的 \(from\) 不同则可以建立路径 \({from}_u \rightarrow {from}_v\), 距离 \({dis}_u+{dis}_v+w_e\)。然后再用 MST 求解即可。
  • 总时间复杂度为 \(O(n\log n)\)。

代码

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=2e5 + 7;
const LL inf=1e13;
int n,m,s,edc,q;
int head[N],vis[N],from[N],par[N],ans[N];
LL dis[N];
struct qry{
int u,v,id;LL d;
bool operator <(const qry &rhs)const{
return d<rhs.d;
}
}A[N],B[N];
struct edge{
int lst,to,c;
edge(){}edge(int lst,int to,int c):lst(lst),to(to),c(c){}
}e[N*4];
void Add(int a,int b,int c){
e[++edc]=edge(head[a],b,c),head[a]=edc;
e[++edc]=edge(head[b],a,c),head[b]=edc;
}
struct data{
int u;LL dis;
data(){}data(int u,LL dis):u(u),dis(dis){}
bool operator <(const data &rhs)const{
return rhs.dis<dis;
}
};
priority_queue<data>Q;
int getpar(int a){
return par[a]==a?a:par[a]=getpar(par[a]);
}
int main(){
n=gi(),s=gi(),m=gi();
rep(i,1,n) par[i]=i;
rep(i,1,n) dis[i]=inf;
rep(i,1,s) {
int x=gi();
dis[x]=0;from[x]=x;
Q.push(data(x,dis[x]));
}
rep(i,1,m) {
A[i].u=gi(),A[i].v=gi(),A[i].d=gi();
Add(A[i].u,A[i].v,A[i].d);
}
while(!Q.empty()){
int u=Q.top().u;Q.pop();
if(vis[u]) continue;vis[u]=1;
go(u)if(dis[u]+e[i].c<dis[v]){
dis[v]=dis[u]+e[i].c;
from[v]=from[u];
Q.push(data(v,dis[v]));
}
}
int cnt=0;
rep(i,1,m){
if(from[A[i].u]==from[A[i].v]) continue;
A[++cnt]=(qry){from[A[i].u],from[A[i].v],0,dis[A[i].u]+dis[A[i].v]+A[i].d};
}
q=gi();
rep(i,1,q)
B[i].u=gi(),B[i].v=gi(),B[i].d=gi(),B[i].id=i; sort(A+1,A+1+cnt);
sort(B+1,B+1+q);
A[cnt+1].d=inf;
int now=1;
rep(i,1,q){
for(;now<=cnt&&A[now].d<=B[i].d;++now){
int x=A[now].u,y=A[now].v;
par[getpar(x)]=getpar(y);
}
ans[B[i].id]=getpar(B[i].u)==getpar(B[i].v);
}
rep(i,1,q) puts(ans[i]?"TAK":"NIE");
return 0;
}

[BZOJ4144][AMPPZ2014]Petrol[多源最短路+MST]的更多相关文章

  1. 4144: [AMPPZ2014]Petrol (多源最短路+最小生成树+启发式合并)

    4144: [AMPPZ2014]Petrol Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 752  Solved: 298[Submit][Sta ...

  2. bzoj4144 [AMPPZ2014]Petrol

    link 题意: 给一个n个点m条边的带权无向图,其中k个点是加油站,每个加油站可以加满油,但不能超过车的油量上限.有q个询问,每次给出x,y,b,保证x,y都是加油站,问一辆油量上限为b的车从x出发 ...

  3. BZOJ4144 [AMPPZ2014]Petrol 【最短路 + 最小生成树】

    题目链接 BZOJ4144 题解 这题好妙啊,,orz 假设我们在一个非加油站点,那么我们一定是从加油站过来的,我们剩余的油至少要减去这段距离 如果我们在一个非加油站点,如果我们到达不了任意加油站点, ...

  4. BZOJ4144: [AMPPZ2014]Petrol(最短路 最小生成树)

    题意 题目链接 Sol 做的时候忘记写题解了 可以参考这位大爷 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  5. 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树

    [BZOJ4144][AMPPZ2014]Petrol Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油 ...

  6. 【BZOJ4144】[AMPPZ2014]Petrol(最短路+最小生成树+并查集)

    Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油站可以补满. q次询问,每次给出x,y,b,表示出发点是 ...

  7. BZOJ 4144: [AMPPZ2014]Petrol

    4144: [AMPPZ2014]Petrol Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 457  Solved: 170[Submit][Sta ...

  8. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  9. [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)

    Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...

随机推荐

  1. tomcat报错this web application instance has been stopped already问题

    上网搜了下,大部分的报错原因:重启时候 之前的tomcat未正常关闭 ,导致在重启时候 报了这个问题.mac下解决: ps -ef|grep tomcat 找到在进行的tomcat ,kill -9  ...

  2. 使用托管快照创建作为 Azure 托管磁盘存储的 VHD 的副本

    创建快照 创建 OS 或数据磁盘 VHD 的快照,以便将其用作备份或用于排查 VM 问题. 快照是 VHD 的完整只读副本. 使用 Azure 门户创建快照 登录到 Azure 门户. 首先在左上角单 ...

  3. Python处理Windows事件日志(json)

    通过NXlog将Windows事件日志保存为json格式文件,然后在Python中使用json.loads()进行处理. NXlog在将Windows事件日志保存为json格式文件,文件中带入了BOM ...

  4. java基础学习总结——异常处理

    一.异常的概念 异常指的是运行期出现的错误,也就是当程序开始执行以后执行期出现的错误.出现错误时观察错误的名字和行号最为重要.

  5. Python学习--Selenium模块学习(2)

    Selenium的基本操作 获取浏览器驱动寻找方式 1. 通过手动指定浏览器驱动路径2. 通过 `$PATH`环境变量找寻浏览器驱动 可参考Python学习--Selenium模块简单介绍(1) 控制 ...

  6. List特有迭代器--ListIterator的特殊功能

    /** *    >列表迭代器: *            ListIterator listIterator():List集合特有的迭代器 *            该迭代器继承了Iterat ...

  7. linux安装mydumper软件包以及报错解决

    今天使用mydumper命令从AWS上的RDS集群MYSQL数据库导出数据,发现Tidb官方提供的工具不太适合,所以就自己编译了一个来尝试一下,居然成功了. 首先我的系统是Centos7,并且已经安装 ...

  8. Javaweb学习(三):Servlet程序

    好了,既然开发环境已经配置好了.那么我们首先要搞定得便是servlet了,至于为什么不先去研究jsp,这是因为jsp与servlet本就是一体两面,jsp其本身经过编译.载入.转化等步骤最终会成为se ...

  9. python 下 安装openCV

    安装openCV openCV是Intel 创建的计算机视觉库,用于计算机图像处理. 安装anaconda,在命令行中输入conda install cv2/opencv 报错汇总 网络连接问题 报错 ...

  10. 【Ansible 文档】【译文】网络支持

    Networking Support 网络支持 Working with Networking Devices 使用网络设备 自从Ansible 2.1开始,你现在可以使用成熟模型 - 编写 play ...