题意

给定一个\(n\)个点、\(m\)条边的带权无向图,其中有\(s\)个点是加油站。每辆车都有一个油量上限\(b\),即每次行走距离不能超过\(b\),但在加油站可以补满。\(q\)次询问,每次给出\(x,y,b\),表示出发点是\(x\),终点是\(y\),油量上限为\(b\),且保证\(x\)点和\(y\)点都是加油站,请回答能否从\(x\)走到\(y\)。(\(2 \le s \le n \le 200000, 1 \le m \le 200000\))

分析

首先来分析如果只有一个询问,给出\(x\)点和\(y\)点问\(x\)是否能走到\(y\)。假设经过的非加油站的点集依次是\(p_1, p_2, \cdots, p_k\),那么考虑从\(p_1\)走到\(p_2\),假设有边\((p_1, p_2)\)(否则一定是从加油站走到\(p_2\)的),权值为\(w\)。如果我们从\(p_1\)走到最近的加油站(距离为\(d(p_1)\))加满油再回来,还剩的油为\(b-d(p_1)\),然后再走这条边。而如果直接从\(p_1\)走到\(p_2\),由于没有加油,此时在\(p_1\)的油量显然是\(\le b-d(p_1)\)的。显然加了油更优。

题解

根据分析,我们只需要按新赋值的边权w+d(u)+d(v)生成最小生成树来判断即可。对于询问,离线一下即可。

#include <bits/stdc++.h>
using namespace std;
const int N=200005, M=200005;
int ihead[N], cnt, n, m, s, p[N], h[N], c[N];
struct E {
int next, to, w;
}e[M<<1];
struct ED {
int x, y, d;
}ed[M];
struct QU {
int x, y, b, id;
}q[N];
void add(int x, int y, int w) {
e[++cnt]=(E){ihead[x], y, w}; ihead[x]=cnt;
e[++cnt]=(E){ihead[y], x, w}; ihead[y]=cnt;
}
int find(int x) {
return x==p[x]?x:p[x]=find(p[x]);
}
typedef pair<int, int> pii;
#define mkpii make_pair<int, int>
priority_queue<pii, vector<pii>, greater<pii> > qu;
int d[N], vis[N];
void dij() {
memset(d, 0x7f, sizeof(int)*(n+1));
for(int i=0; i<s; ++i) {
d[c[i]]=0;
qu.push(mkpii(0, c[i]));
}
while(qu.size()) {
int x=qu.top().second;
qu.pop();
if(vis[x]) {
continue;
}
vis[x]=1;
for(int i=ihead[x]; i; i=e[i].next) {
int y=e[i].to;
if(d[y]>d[x]+e[i].w) {
d[y]=d[x]+e[i].w;
qu.push(mkpii(d[y], y));
}
}
}
}
inline bool cmp1(const ED &a, const ED &b) {
return a.d<b.d;
}
inline bool cmp2(const QU &a, const QU &b) {
return a.b<b.b;
}
int ans[N];
int main() {
scanf("%d%d%d", &n, &s, &m);
for(int i=1; i<=n; ++i) {
p[i]=i;
h[i]=1;
}
for(int i=0; i<s; ++i) {
scanf("%d", &c[i]);
}
for(int i=0; i<m; ++i) {
scanf("%d%d%d", &ed[i].x, &ed[i].y, &ed[i].d);
add(ed[i].x, ed[i].y, ed[i].d);
}
dij();
for(int i=0; i<m; ++i) {
ed[i].d+=d[ed[i].x]+d[ed[i].y];
}
int Q;
scanf("%d", &Q);
for(int i=0; i<Q; ++i) {
scanf("%d%d%d", &q[i].x, &q[i].y, &q[i].b);
q[i].id=i;
}
sort(ed, ed+m, cmp1);
sort(q, q+Q, cmp2);
int now=0;
for(int i=0; i<Q; ++i) {
while(now<m && ed[now].d<=q[i].b) {
int fx=find(ed[now].x), fy=find(ed[now].y);
if(fx!=fy) {
if(h[fx]>h[fy]) {
swap(fx, fy);
}
p[fx]=fy;
h[fy]+=h[fy]==h[fx];
}
++now;
}
ans[q[i].id]=find(q[i].x)==find(q[i].y);
}
for(int i=0; i<Q; ++i) {
puts(ans[i]?"TAK":"NIE");
}
return 0;
}

【BZOJ】4144: [AMPPZ2014]Petrol的更多相关文章

  1. 【BZOJ】4147: [AMPPZ2014]Euclidean Nim

    [算法]博弈论+数论 [题意]给定n个石子,两人轮流操作,规则如下: 轮到先手操作时:若石子数<p添加p个石子,否则拿走p的倍数个石子.记为属性p. 轮到后手操作时:若石子数<q添加q个石 ...

  2. 【BZOJ】4152: [AMPPZ2014]The Captain【SLF优化Spfa】

    4152: [AMPPZ2014]The Captain Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 2107  Solved: 820[Submi ...

  3. 【BZOJ】【4144】【AMPPZ2014】Petrol

    最短路+最小生成树+倍增 图论问题中综合性较强的一题= =(Orz vfk) 比较容易发现,关键的还是有加油站的这些点,其他点都是打酱油的. 也就是说我们重点是要求出 关键点之间的最短路. 这玩意…… ...

  4. BZOJ 4144: [AMPPZ2014]Petrol

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

  5. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  6. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  7. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  8. 【BZOJ】1013: [JSOI2008]球形空间产生器sphere

    [BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...

  9. 【BZOJ】1002:轮状病毒(基尔霍夫矩阵【附公式推导】或打表)

    Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...

随机推荐

  1. Python复习之生成器 generator

    生成器 generator def h(): print "hello" m = yield 5 print "m:", m d = yield 12 prin ...

  2. vi编辑器使用

    显示行号 set nu 取消行号 set nonu 定位到某一行 gg 定位到首行 G 定位到最后一行 在VI编辑器中切换调用外部shell命令 :!ifconfig   在编辑过程中,看ip地址 插 ...

  3. jQuery插件开发代码

    方法和原理在这篇博文中非常详细易懂 http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html 下面整理下基本知识点和基本的代码段: jQue ...

  4. Python之mmap内存映射模块(大文本处理)说明

    背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过 ...

  5. Ansible 模块命令介绍

    copy模块: 目的:把主控端/root目录下的a.sh文件拷贝到到指定节点上 命令:ansible 10.1.1.113 -m copy -a 'src=/root/a.sh dest=/tmp/' ...

  6. iOS 实例变量修饰符

    @public 可以在其他类中访问被@public修饰的成员变量 可以在本类中访问被@public修饰的成员变量 可以在子类中访问fl中被@public修饰的成员变量 @private 不可以在其他类 ...

  7. Linux 搭建Java web服务器

    未经允许,不得转载 1.jdk的下载与配置 1.1下载 sudo wget http://download.oracle.com/otn-pub/java/jdk/8u45-b14/jdk-8u45- ...

  8. SerialPort 串口开发

    private SerialPort sPort = new SerialPort(); //串行端口资源 /// <summary> /// 函数功能:打开串口/关闭串口 /// < ...

  9. ASP.NET知识总结(8.AJAX异步)

    AJAX:”Asynchronous JavaScript and XML” 中文意思:异步JavaScript和XML. 指一种创建交互式网页应用的网页开发技术.   不是指一种单一的技术,而是有机 ...

  10. 用winform程序来了解委托和事件

    一.浅谈委托 如果有个过winform 和webform 程序开发的小伙伴一定有个这样的感觉吧,点击Button直接就执行了那个方法,到此他是怎么实现了的呢,大家有考虑过没有? 回到正题,什么是委托呢 ...