题意

题目链接

分析

  • 由于起点和终点都是加油站,所以我们可以把整个问题看成是从加油站到加油站。
  • 考虑一个暴力的做法,用最短路在 \(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. 用例设计之APP用例覆盖准则

    基本原则 本文主要讨论APP功能用例的覆盖,基本原则: 用户场景闭环(从哪来到哪去) 遍历所有的实现逻辑路径 需求点覆盖 覆盖维度 APP功能用例设计主要使用传统的黑盒用例设计方法.同时,作为移动AP ...

  2. LeetCode题解之Unique Paths II

    1.题目描述 2.问题描述 使用动态规划算法,加上条件检测即可 3.代码 int uniquePathsWithObstacles(vector<vector<int>>&am ...

  3. 安卓ADB命令

    查看连接的设备 adb devices -l FastBoot常用命令: fastboot erase system    #擦除system分区 fastboot erase boot    #擦除 ...

  4. python 之@staticmethod和@classmethod

    在python中,要调用一个类中的方法,一般的操作步骤如下: 1.实例化此类 2.调用此类中的方法 而@staticmethod和@classmethod则打破了这种引用方式,可以在不实例化类的情况下 ...

  5. Oracle EBS OM 取消订单行

    DECLARE l_header_rec OE_ORDER_PUB.Header_Rec_Type; l_line_tbl OE_ORDER_PUB.Line_Tbl_Type; l_action_r ...

  6. SQL Server 合并复制如何把备份的发布端或订阅端BAK文件还原为数据库

    SQL Server的合并复制,是可以备份发布端和订阅端数据库为BAK文件的,但是问题是合并复制在数据库中自动创建的系统表.触发器.表中的RowGuid列等也会被一起备份. 这里我们举个例子,下面图中 ...

  7. web.config中的InProc模式 与 StateServer模式[转]

    开发asp.net应用时,修改web.config中的SessionState节点. <sessionState mode="StateServer" stateConnec ...

  8. 学习笔记:ALTERing a Huge MySQL Table - 对一个超大表做alter调整

    Table of Contents The ProblemFuture SolutionsOverview of SolutionShortcutAssumptions/Restrictions/Co ...

  9. linux内核完全剖析——基于0.12内核-笔记(1)-CPU 数据通信

    CPU数据通信总线 CPU通过地址线.数据线.控制信号组成的本地总线(或称为内部总线)与系统其它部分进行数据通信. 地址总线 地址总线用于内存或I/O设备的地址,即指明需要读/写数据的具体位置. 数据 ...

  10. Unity Mono

    Unity的mscrolib.dll和.Net的mscrolib.dll 好奇于Unity的mscrolib.dll和.Net Framework提供的mscrolib是否一致. .Net的mscro ...