Description

给定一个n个点、m条边的带权无向图,其中有s个点是加油站。

每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油站可以补满。

q次询问,每次给出x,y,b,表示出发点是x,终点是y,油量上限为b,且保证x点和y点都是加油站,请回答能否从x走到y。

Input

第一行包含三个正整数n,s,m(2<=s<=n<=200000,1<=m<=200000),表示点数、加油站数和边数。

第二行包含s个互不相同的正整数c[1],c[2],...cs,表示每个加油站。

接下来m行,每行三个正整数u[i],v[i],di,表示u[i]和v[i]之间有一条长度为d[i]的双向边。

接下来一行包含一个正整数q(1<=q<=200000),表示询问数。

接下来q行,每行包含三个正整数x[i],y[i],bi,表示一个询问。

Output

输出q行。第i行输出第i个询问的答案,如果可行,则输出TAK,否则输出NIE。

Sample Input

6 4 5

1 5 2 6

1 3 1

2 3 2

3 4 3

4 5 5

6 4 5

4

1 2 4

2 6 9

1 5 9

6 5 8

Sample Output

TAK

TAK

TAK

NIE

题解

居然是权限题……

不难发现我们需要的是加油站之间的最短路,然而肯定不能直接跑否则会\(gg\)

考虑一条边\((u,v)\),如果我们要从加油站\(a\)到\(b\),且这条路经过\((u,v)\),设\(c\)为到\(u\)最近的加油站,\(d\)为到\(v\)最近的加油站,最优策略肯定是从\(a\)到\(c\),从\(c\)到\(d\),从\(d\)到\(b\),因为这里面每一次的加油站之间的转移的距离都要小于从\(a\)直接走到\(b\)

那么我们可以做一个多源最短路,记录\(las_i\)表示离\(i\)最近的加油站,\(dis_i\)表示\(i\)到\(las_i\)的距离

对于一条边\((u,v)\),如果\(las_u=las_v\),那么这条边显然对加油站之间的最短路是无所谓的

否则的话,我们在新图中加入边\((las_u,las_v,dis_u+dis_v+(u,v))\)

那么把询问离线,按边权排序,用最小生成树和并查集解决就行了

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=2e5+5;
struct eg{int v,nx,w;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v,R int w){e[++tot]={v,head[u],w},head[u]=tot;}
struct node{
int u,d;
node(){}
node(R int u,R int d):u(u),d(d){}
inline bool operator <(const node &b)const{return d>b.d;}
};priority_queue<node>q;
struct EG{
int u,v,w,id;
EG(){}
EG(R int u,R int v,R int w,R int id=0):u(u),v(v),w(w),id(id){}
inline bool operator <(const EG &b)const{return w<b.w;}
}E[N],Q[N];
int dis[N],las[N],vis[N],fa[N],ans[N],n,m,s,qaq,u,v,w,cnt;
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void merge(R int u,R int v){
u=find(u),v=find(v);
fa[u]=v;
}
int main(){
freopen("petrol.in","r",stdin);
freopen("petrol.out","w",stdout);
memset(dis,0x3f,sizeof(dis));
n=read(),s=read(),m=read();
fp(i,1,s)u=read(),las[u]=u,dis[u]=0,q.push(node(u,0));
fp(i,1,m)u=read(),v=read(),w=read(),add(u,v,w),add(v,u,w);
while(!q.empty()){
int u=q.top().u;q.pop();
if(vis[u])continue;vis[u]=1;
go(u)if(cmin(dis[v],dis[u]+e[i].w))las[v]=las[u],q.push(node(v,dis[v]));
}
fp(u,1,n)go(u)if(las[u]<las[v])E[++cnt]=EG(las[u],las[v],dis[u]+dis[v]+e[i].w);
sort(E+1,E+1+cnt);
qaq=read();
fp(i,1,qaq)Q[i].u=read(),Q[i].v=read(),Q[i].w=read(),Q[i].id=i;
sort(Q+1,Q+1+qaq);
fp(i,1,n)fa[i]=i;
for(R int i=1,j=1;i<=qaq;++i){
while(j<=cnt&&E[j].w<=Q[i].w)merge(E[j].u,E[j].v),++j;
ans[Q[i].id]=(find(Q[i].u)==find(Q[i].v));
}
fp(i,1,qaq)puts(ans[i]?"TAK":"NIE");
return 0;
}

【BZOJ4144】[AMPPZ2014]Petrol(最短路+最小生成树+并查集)的更多相关文章

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

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

  2. CSP 201703-4 地铁修建【最小生成树+并查集】

    问题描述 试题编号: 201703-4 试题名称: 地铁修建 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市 ...

  3. UVA 1395 苗条的生成树(最小生成树+并查集)

    苗条的生成树 紫书P358 这题最后坑了我20分钟,怎么想都对了啊,为什么就wa了呢,最后才发现,是并查集的编号搞错了. 题目编号从1开始,我并查集编号从0开始 = = 图论这种题真的要记住啊!!题目 ...

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

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

  5. 关于最小生成树(并查集)prime和kruskal

    适合对并查集有一定理解的人.  新手可能看不懂吧.... 并查集简单点说就是将相关的2个数字联系起来 比如 房子                      1   2    3   4  5   6 ...

  6. bzoj 3559: [Ctsc2014]图的分割【最小生成树+并查集】

    读题两小时系列-- 在读懂题意之后,发现M(c)就是c这块最大权割边也就是的最小生成树的最大权边的权值,所以整个问题都可以在MST的过程中解决(M和c都是跟着并查集变的) 不过不是真的最小生成树,是合 ...

  7. [USACO09JAN]安全出行Safe Travel 最短路,并查集

    题目描述 Gremlins have infested the farm. These nasty, ugly fairy-like creatures thwart the cows as each ...

  8. Regional Changchun Online--Travel(最小生成树&& 并查集)

    Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  9. UOJ14 UER #1 DZY Loves Graph(最小生成树+并查集)

    显然可以用可持久化并查集实现.考虑更简单的做法.如果没有撤销操作,用带撤销并查集暴力模拟即可,复杂度显然可以均摊.加上撤销操作,删除操作的复杂度不再能均摊,但注意到我们在删除时就可以知道他会不会被撤销 ...

随机推荐

  1. 大数据_学习_01_Hadoop 2.x及hbase常用端口及查看方法

    二.参考资料 1.Hadoop 2.x常用端口及查看方法

  2. 一次websocket的抓包体验

    一个简单的demo 我们知道websocket一种服务端推送技术,首先Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手.后续数据传递是基于TCP的. 客户端代码 &l ...

  3. 关于linux 安装 python pymssql模块

    需要先安装freetds是一个开源的C程序库,它可以实现在Linux系统下访问操作微软的SQL数据库.可以用在Sybase的db-lib或者ct-lib库,在里面也包含了一个ODBC的库.允许许多应用 ...

  4. CH5103 [NOIP2008]传纸条[线性DP]

    给定一个 N*M 的矩阵A,每个格子中有一个整数.现在需要找到两条从左上角 (1,1) 到右下角 (N,M) 的路径,路径上的每一步只能向右或向下走.路径经过的格子中的数会被取走.两条路径不能经过同一 ...

  5. POJ1422 Air Raid 和 CH6902 Vani和Cl2捉迷藏

    Air Raid Language:Default Air Raid Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9547 A ...

  6. bzoj 2716 [Violet 3]天使玩偶——KDtree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2716 第三道KDtree!仍旧是模板.还有CDQ分治做法,见下面. 数组迷之开大?(开6e5 ...

  7. wpf dataGrid 选中行 失去焦点时 的背景颜色的更改

    关于 wpf dataGrid 选中行 失去焦点时 的背景颜色的更改.很简单的方式,在datagrid的resource中更改InactiveSelectionHighlightBrushKey属性的 ...

  8. Python selenium 三种等待方法

    1. 强制等待 sleep(xx) 是最简单粗暴的一种办法,不管你浏览器是否加载完了,程序都得等待3秒,3秒一到,继续执行下面的代码,作为调试很有用,不建议总用这种等待方式,严重影响程序执行速度. 代 ...

  9. Java变量初始化的讲解

    首先需要说明的是Java中的变量分为两种:成员变量和局部变量 其中成员变量又可分为:实例变量(非静态变量)和类变量(静态变量) 局部变量(局部变量的作用时间很短,所以一般是存储在栈中的): 1.形参在 ...

  10. Random简介

    Random类 (java.util) Random类中实现的随机算法是伪随机,也就是有规则的随机.在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要 ...