4144: [AMPPZ2014]Petrol

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 457  Solved: 170
[Submit][Status][Discuss]

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],...c[s](1<=c[i]<=n),表示每个加油站。
接下来m行,每行三个正整数u[i],v[i],d[i](1<=u[i],v[i]<=n,u[i]!=v[i],1<=d[i]<=10000),表示u[i]和v[i]之间有一条长度为d[i]的双向边。
接下来一行包含一个正整数q(1<=q<=200000),表示询问数。
接下来q行,每行包含三个正整数x[i],y[i],b[i](1<=x[i],y[i]<=n,x[i]!=y[i],1<=b[i]<=2*10^9),表示一个询问。
 

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

HINT

 

Source

[Submit][Status][Discuss]

分析

为了回答每个询问,我们需要加油站之间的最小生成树。

求最小生成树的方式是:让所有的加油站dis为0,做多源最短路,同时记录距离每个点最近的加油站。然后枚举边,可以得到两个加油站之间的可能最短距离。做Kruskal或Prim即可。

求到最小生成树之后,用倍增法维护路径上的最大权值即可。

代码

 #include <cmath>
 #include <queue>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <iostream>
 #include <algorithm>

 using namespace std;

 #define N 500005
 #define inf 0x3f3f3f3f

 int n, m, s, c[N];

 struct edge
 {
     int x, y, w;

     edge(void) {};
     edge(int _x, int _y, int _w) :
         x(_x), y(_y), w(_w) {};

     friend bool operator < (const edge &a, const edge &b)
     {
         return a.w < b.w;
     }
 };

 struct step
 {
     int id, dis;

     step(void) {};
     step(int a, int b) :
         id(a), dis(b) {};

     friend bool operator < (const step &a, const step &b)
     {
         return a.dis > b.dis;
     }
 };

 namespace kirito
 {
     edge e[N]; ;

     int hd[N], to[N], vl[N], nt[N], tot;

     void addEdge(int x, int y, int w)
     {
         nt[tot] = hd[x]; to[tot] = y; vl[tot] = w; hd[x] = tot++;
         nt[tot] = hd[y]; to[tot] = x; vl[tot] = w; hd[y] = tot++;
     }

     int dis[N], from[N]; 

     priority_queue<step> pq;
 }

 namespace masiro
 {
     edge e[N]; ;

     void pushEdge(int x, int y, int w)
     {
         e[++edge_cnt] = edge(x, y, w);
     }

     int hd[N], to[N], vl[N], nt[N], tot;

     void addEdge(int x, int y, int w)
     {
         nt[tot] = hd[x]; to[tot] = y; vl[tot] = w; hd[x] = tot++;
         nt[tot] = hd[y]; to[tot] = x; vl[tot] = w; hd[y] = tot++;
     }

     int fa[N];

     int find(int u)
     {
         return fa[u] == u ? u : fa[u] = find(fa[u]);
     }

     int root;

     ], mex[N][];

     void predfs(int u, int f)
     {
         ; i < ; ++i)
         {
             fat[u][i] = fat[fat[u][i - ]][i - ];
             mex[u][i] = max(mex[u][i - ], mex[fat[u][i - ]][i - ]);
         }

         for (int i = hd[u]; ~i; i = nt[i])
             if (to[i] != f)
             {
                 dep[to[i]] = dep[u] + ;
                 mex[to[i]][] = vl[i];
                 fat[to[i]][] = u;
                 predfs(to[i], u);
             }
     }
 }

 void prework1(void)
 {
     using namespace kirito;

     memset(dis, inf, sizeof(dis)); 

     ; i <= s; ++i)
     {
         dis[c[i]] = ;
         from[c[i]] = c[i];
         pq.push(step(c[i], ));
     }

     while (!pq.empty())
     {
         step top = pq.top(); pq.pop();

         if (dis[top.id] != top.dis)
             continue;

         for (int i = hd[top.id]; ~i; i = nt[i])
             if (dis[to[i]] > vl[i] + top.dis)
             {
                 from[to[i]] = from[top.id];
                 dis[to[i]] = vl[i] + top.dis;
                 pq.push(step(to[i], dis[to[i]]));
             }
     }

     ; i <= m; ++i)
         if (from[e[i].x] ^ from[e[i].y])
             masiro::pushEdge(from[e[i].x], from[e[i].y], dis[e[i].x] + dis[e[i].y] + e[i].w);
 }

 void prework2(void)
 {
     using namespace masiro;

     sort(e + , e +  + edge_cnt);

     ; i <= n; ++i)
         fa[i] = i;

     ; i <= edge_cnt; ++i)
     {
         int fx = find(e[i].x);
         int fy = find(e[i].y);

         if (fx ^ fy)
         {
             fa[fx] = fy;
             addEdge(e[i].x, e[i].y, e[i].w);
         }
     }

     root = n + ; 

     ; i <= s; ++i)
         if (find(c[i]) == c[i])
             addEdge(root, c[i], inf);

     dep[root] = ;
     fat[root][] = root;
     memset(mex, , sizeof(mex));

     predfs(root, -);
 }

 int lca(int x, int y)
 {
     using namespace masiro;

     ;

     if (dep[x] < dep[y])
         swap(x, y);

     ; i >= ; --i)
         if (dep[fat[x][i]] >= dep[y])
         {
             res = max(res, mex[x][i]);
             x = fat[x][i];
         }

     if (x == y)
         return res;

     ; i >= ; --i)
         if (fat[x][i] != fat[y][i])
         {
             res = max(res, mex[x][i]);
             res = max(res, mex[y][i]);
             x = fat[x][i];
             y = fat[y][i];
         }

     res = max(res, mex[x][]);
     res = max(res, mex[y][]);

     return res;
 }

 signed main(void)
 {
     scanf("%d%d%d", &n, &s, &m);

     ; i <= s; ++i)
         scanf("%d", c + i);

     memset(kirito::hd, -, sizeof(kirito::hd));
     memset(masiro::hd, -, sizeof(masiro::hd));

     ; i <= m; ++i)
     {
         int x, y, w; scanf("%d%d%d", &x, &y, &w);

         kirito::addEdge(x, y, w);
         kirito::e[i] = edge(x, y, w);
     }

     prework1();
     prework2(); 

     int q; scanf("%d", &q);

     ; i <= q; ++i)
     {
         int x, y, w; scanf("%d%d%d", &x, &y, &w);

         int maxCost = lca(x, y);

         if (w >= maxCost)
             puts("TAK");
         else
             puts("NIE");
     }
 }

BZOJ_4144.cpp

@Author: YouSiki

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

  1. 【BZOJ】4144: [AMPPZ2014]Petrol

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

  2. 循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain

    循环队列基础知识 1.循环队列需要几个参数来确定 循环队列需要2个参数,front和rear 2.循环队列各个参数的含义 (1)队列初始化时,front和rear值都为零: (2)当队列不为空时,fr ...

  3. BZOJ 4152: [AMPPZ2014]The Captain( 最短路 )

    先按x排序, 然后只有相邻节点的边才有用, 我们连起来, 再按y排序做相同操作...然后就dijkstra ---------------------------------------------- ...

  4. BZOJ 4143: [AMPPZ2014]The Lawyer( sort )

    水题... 排序搞出每天的会议有哪些, 然后再按照会议的开始时间和结束时间排序, 最晚开始的和最早结束的会议不是同一场而且最晚开始的时间>最早结束的会议就有可能方案 -------------- ...

  5. BZOJ 4145: [AMPPZ2014]The Prices( 状压dp + 01背包 )

    我自己只能想出O( n*3^m )的做法....肯定会T O( nm*2^m )做法: dp( x, s ) 表示考虑了前 x 个商店, 已买的东西的集合为s. 考虑转移 : 先假设我们到第x个商店去 ...

  6. BZOJ 4146 [AMPPZ2014] Divisors 解题报告

    这个题感觉比较小清新... 我们记录每个数出现的次数 $T_i$. 首先依次枚举每个数字,令 $ans = ans + T_i \times (T_i - 1)$,然后枚举这个数的倍数,令 $ans ...

  7. AMPPZ2014

    [AMPPZ2014]The Lawyer 记录每天结束的最早的会议以及开始的最晚的会议即可. #include<cstdio> #define N 500010 int n,m,i,d, ...

  8. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  9. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

随机推荐

  1. 基于Caffe的Large Margin Softmax Loss的实现(中)

    小喵的唠叨话:前一篇博客,我们做完了L-Softmax的准备工作.而这一章,我们开始进行前馈的研究. 小喵博客: http://miaoerduo.com 博客原文:  http://www.miao ...

  2. 初识Azkaban

    先说下hadoop 内置工作流的不足 (1)支持job单一 (2)硬编码 (3)无可视化 (4)无调度机制 (5)无容错机制 在这种情况下Azkaban就出现了 1)Azkaban是什么 Azkaba ...

  3. SQL Server执行计划的理解

    详细看:http://www.cnblogs.com/kissdodog/p/3160560.html 自己总结: 扫描Scan:逐行遍历数据. 查找Seek:根据查询条件,定位到索引的局部位置,然后 ...

  4. sql优化之not in

    sql : select ID from awhere XX <> 0 and ID not in (select ID from b) 4万多条记录,执行了316秒,无法接受.   优化 ...

  5. Mac下DIY文件浏览器

    2015-07-14 15:07:53 Mac下的finder不能浏览Linux文件目录, 一些优秀的资源管理器是收费的..... 于是想到了既然Mac的本质是类Unix, 而在windows下查看L ...

  6. August 31st 2016 Week 36th Tuesday

    A friend without faults will never be found. 没有缺点的朋友是永远找不到的. You can't find a friends without faults ...

  7. DSP using MATLAB 示例Example3.22

    代码: % Discrete-time Signal x2(n) Ts = 0.001; n = -5:1:5; nTs = n*Ts; Fs = 1/Ts; x = exp(-1000*abs(nT ...

  8. Mac下android_sdk配置环境变量

    1.启动Terminal终端工具 2.输入cd ~/ 进入当前用户的home目录 3. 创建: touch .bash_profile 4.打开并编辑: open .bash_profile 5.在文 ...

  9. Linux系统下安装rz/sz命令及使用说明

    对于经常使用Linux系统的人员来说,少不了将本地的文件上传到服务器或者从服务器上下载文件到本地,rz / sz命令很方便的帮我们实现了这个功能,但是很多Linux系统初始并没有这两个命令.今天,我们 ...

  10. jQuery 清除div内容

    $.ajax({            url: "SearchSN.aspx",            data: "SN=" + $("#txtS ...