题目链接

BZOJ4144

题解

这题好妙啊,,orz

假设我们在一个非加油站点,那么我们一定是从加油站过来的,我们剩余的油至少要减去这段距离

如果我们在一个非加油站点,如果我们到达不了任意加油站点,我们一定废了

那么我们在一个非加油站点,就一定可以到达最近的加油站,而由于我们剩余的油是要减去到加油站距离的,所以我们剩余的油一定是\(b - d\),\(d\)表示到达最近加油站的距离。假如我们没有那么多油,我们一定可以开过去再回来,就有了

因此,我们在任意一个点的油量确定,两点之间可以直达,当且仅当

①两点间有边

②\(w + d[u] + d[v] \le b\)

因此可以以此为新边权跑最小生成树,同时离线回答询问

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 200005,maxm = 400005,INF = 2000000026;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int n,s,m,Q,c[maxn];
int h[maxn],ne;
struct EDGE{int to,nxt,w;}ed[maxm];
inline void build(int u,int v,int w){
ed[++ne] = (EDGE){v,h[u],w}; h[u] = ne;
ed[++ne] = (EDGE){u,h[v],w}; h[v] = ne;
}
struct edge{int a,b,w;}e[maxn];
inline bool operator < (const edge& a,const edge& b){
return a.w < b.w;
}
struct Que{int u,v,b,id;}q[maxn];
inline bool operator < (const Que& a,const Que& b){
return a.b < b.b;
}
priority_queue<cp,vector<cp>,greater<cp> > qu;
int vis[maxn],d[maxn];
void dijkstra(){
for (int i = 1; i <= n; i++) d[i] = INF;
for (int i = 1; i <= s; i++)
d[c[i]] = 0,qu.push(mp(0,c[i]));
int u;
while (!qu.empty()){
u = qu.top().second; qu.pop();
if (vis[u]) continue;
vis[u] = true;
Redge(u) if (!vis[to = ed[k].to] && d[u] + ed[k].w < d[to]){
d[to] = d[u] + ed[k].w;
qu.push(mp(d[to],to));
}
}
}
int ans[maxn],pre[maxn];
inline int find(int u){return u == pre[u] ? u : pre[u] = find(pre[u]);}
void kruskal(){
REP(i,m) e[i].w = e[i].w + d[e[i].a] + d[e[i].b];
sort(e + 1,e + 1 + m);
int t = 1,fa,fb;
REP(i,n) pre[i] = i;
for (int i = 1; i <= m; i++){
while (t <= Q && e[i].w > q[t].b){
ans[q[t].id] = (find(q[t].u) == find(q[t].v));
t++;
}
fa = find(e[i].a); fb = find(e[i].b);
if (fa != fb) pre[fb] = fa;
}
while (t <= Q){
ans[q[t].id] = (find(q[t].u) == find(q[t].v));
t++;
}
}
int main(){
n = read(); s = read(); m = read();
REP(i,s) c[i] = read();
REP(i,m){
e[i].a = read(); e[i].b = read(); e[i].w = read();
build(e[i].a,e[i].b,e[i].w);
}
Q = read();
REP(i,Q) q[i].u = read(),q[i].v = read(),q[i].b = read(),q[i].id = i;
sort(q + 1,q + 1 + Q);
dijkstra();
kruskal();
REP(i,Q) 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. 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树

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

  3. [BZOJ4144][AMPPZ2014]Petrol[多源最短路+MST]

    题意 题目链接 分析 假设在 \(a \rightarrow b\) 的最短路径中出现了一个点 \(x\) 满足到 \(x\) 最近的点是 \(c\) ,那么我们完全可以从 \(a\) 直接走到 \( ...

  4. bzoj4144 [AMPPZ2014]Petrol

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

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

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

  6. BZOJ 4144: [AMPPZ2014]Petrol

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

  7. Day3 最短路 最小生成树 拓扑排序

    Day3 最短路 最小生成树 拓扑排序 (一)最短路 一.多源最短路 从任意点出发到任意点的最短路 1. Floyd \(O(n^3)\) for(int k=1;k<=n;k++) for(i ...

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

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

  9. BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)

    BZOJ 看别人代码的时候发现哪一步都很眼熟,突然想起来,就在四个月前我好像看过还给别人讲过?mmp=v= 果然不写写就是容易忘.写了好歹忘了的时候还能复习呢(虽然和看别人的好像也没多少差别?). 首 ...

随机推荐

  1. 使用Python访问HDFS

    最近接触到大数据,对于Skpark和Hadoop的料及都停留在第一次听到这个名词时去搜一把看看大概介绍免得跟不上时代的层次. 在实际读了点别人的代码,又自己写了一些之后,虽然谈不上理解加深,至少对于大 ...

  2. InnoDB锁冲突案例演示(续)

      Preface       I've demontstrated several InnoDB locking cases in my previous blog.I'm gonna do the ...

  3. java对象创建过程简介

    这是看书的记录,字有点丑啊还是将就搬上来 -.-,等把后面看了完善图

  4. Python3 Tkinter-Entry

    1.创建 from tkinter import * root=Tk() t1=Entry(root) t1.pack() root.mainloop() 2.绑定变量 from tkinter im ...

  5. Linux下实现Rsync目录同步备份

    需求:对于开发机器做目录的数据备份 测试机IP:192.168.1.100   WEB目录:/bckup/ 下面我将用一台机器来备份上面测试机 /bckup下的所有数据,并实现时时同步 备份机器IP: ...

  6. 一个改变this指向bind的函数,vue源代码

    function bind(fn, ctx) { return function (a) { var l = arguments.length; return l ? l > 1 ? fn.ap ...

  7. C语言 结构体相关 函数 指针 数组

    . 作者 : 万境绝尘 转载请注明出处 : http://www.hanshuliang.com/?post=30 . 结构体概述 : 结构体是 多个 变量的集合, 变量的类型可以不同; -- 可进行 ...

  8. Android 开发 之 JNI入门 - NDK从入门到精通

    NDK项目源码地址 : -- 第一个JNI示例程序下载 : GitHub - https://github.com/han1202012/NDKHelloworld.git -- Java传递参数给C ...

  9. sigsuspend

    1)头文件:#include <signal.h> 2)一个保护临界区代码的错误实例:(sigprocmask()和pause()实现) #include <unistd.h> ...

  10. 数据存储到MySQL并返回新插入的id值

    当对数据库进行插入数据后,有时会需要刚插入的数据的id值,以作他用,整理如下: conn = pymysql.connect(, user=DB_USER, passwd=DB_PASSWORD, d ...