「AMPPZ2014」Petrol

传送门:
这是一道bzoj权限题
Luogu团队题链接

解题思路

首先对于每一个点 \(x\) 预处理出 \(nr[x]\) 和 \(dis[x]\),分别表示离 \(x\) 最近的加油站以及该段距离。
这个过程可以用多源 \(\text{Dijkstra}\) 处理。
然后对于每一条原图中的边 \((u, v, w)\)(\(nr[u]\ne nr[v]\))
改为这样一条边:\((nr[u], nr[v], dis[u] + dis[v] + w)\)
然后只要离线用并查集维护一下连通性即可。

细节注意事项

  • 最短路不要写挂啊

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <queue>
#define rg register
#define pii pair < int, int >
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

const int _ = 200010;
const int __ = 400010;

int tot, head[_], nxt[__], ver[__], w[__];
inline void Add_edge(int u, int v, int d)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, w[tot] = d; }

int q, n, m, k, c[_], vis[_], dis[_], nr[_];
struct node{ int u, v, d, id; }ask[_], g[__], e[__]; int ans[_];

inline bool cmp(const node& x, const node& y) { return x.d < y.d; }

inline void Dijkstra() {
    static priority_queue < pii > Q;
    memset(dis, 0x3f, sizeof dis);
    for (rg int i = 1; i <= k; ++i)
        Q.push(make_pair(dis[c[i]] = 0, c[i])), nr[c[i]] = c[i];
    while (!Q.empty()) {
        int u = Q.top().second; Q.pop();
        if (vis[u]) continue; vis[u] = 1;
        for (rg int i = head[u]; i; i = nxt[i]) {
            int v = ver[i];
            if (dis[v] > dis[u] + w[i])
                dis[v] = dis[u] + w[i], nr[v] = nr[u], Q.push(make_pair(-dis[v], v));
        }
    }
}

int fa[_];

inline int findd(int x) { return fa[x] == x ? x : fa[x] = findd(fa[x]); }

inline void merge(int x, int y) { fa[findd(x)] = findd(y); }

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
#endif
    read(n), read(k), read(m);
    for (rg int i = 1; i <= k; ++i) read(c[i]);
    for (rg int u, v, d, i = 1; i <= m; ++i)
        read(u), read(v), read(d), Add_edge(u, v, d), Add_edge(v, u, d), g[i] = (node) { u, v, d };
    Dijkstra();
    int cnt = 0;
    for (rg int u, v, i = 1; i <= m; ++i) {
        u = g[i].u, v = g[i].v;
        if (nr[u] != nr[v]) e[++cnt] = (node) { nr[u], nr[v], dis[u] + dis[v] + g[i].d };
    }
    read(q);
    for (rg int i = 1; i <= q; ++i)
        read(ask[i].u), read(ask[i].v), read(ask[i].d), ask[i].id = i;
    sort(ask + 1, ask + q + 1, cmp);
    sort(e + 1, e + cnt + 1, cmp);
    for (rg int i = 1; i <= n; ++i) fa[i] = i;
    for (rg int i = 1, j = 1; i <= q; ++i) {
        while (j <= cnt && e[j].d <= ask[i].d) merge(e[j].u, e[j].v), ++j;
        ans[ask[i].id] = findd(ask[i].u) == findd(ask[i].v);
    }
    for (rg int i = 1; i <= q; ++i) puts(ans[i] ? "TAK" : "NIE");
    return 0;
}

完结撒花 \(qwq\)

原文地址:https://www.cnblogs.com/zsbzsb/p/11745703.html

时间: 2024-08-03 01:27:39

「AMPPZ2014」Petrol的相关文章

「AMPPZ2014」The Captain

传送门: 这是一道bzoj权限题 Luogu团队题链接 解题思路 直接连边的话边数肯定会爆炸,考虑减少边数. 我们画出坐标系,发现一个东西: 对于两个点 \(A,B\),\(|x_A-y_A|\) 可以经由由他们俩之间的若干点取到,\(y\) 同理. 所以我们只需要先把所有点分别按照 \(x\) 和 \(y\),相邻两点之间连边即可. 细节注意事项 不要写挂最短路 参考代码 #include <algorithm> #include <iostream> #include <

AC日记——「HNOI2017」单旋 LiBreOJ 2018

#2018. 「HNOI2017」单旋 思路: set+线段树: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define maxtree maxn<<2 int val[maxtree],tag[maxtree],L[maxtree],R[maxtree],mid[maxtree]; int op[maxn],ki[maxn],bi[maxn],cnt,size,n,ch[maxn]

「随笔」基于当下的思考

马德,说好的技术blog,变成日记本了... 下午的时候莫名其妙的感到很颓废,因为自己的不够强大感到忧虑和危机感十足.现在每每行走在技术的道路上,常觉得如履薄冰,如芒在背. 上大学之前和现在的心态其实差别挺大的,视野的开阔远远不止局限于自己的脚下.不过,这里的「上大学之前」只是一个时间描述词,并不觉得大学是最适合学习的地方,我很失望. 世界上的人无论性别,区域,宗教,兴趣爱好,总可以在互联网上找到志趣相同的人,总是可以不断打破自己的常识与惯性思维.总是有在相同领域比自己更强的人,挺好的. 关于知

「Unity」与iOS、Android平台的整合:3、导出的Android-Studio工程

本文属于「Unity与iOS.Android平台的整合」系列文章之一,转载请注明出处. Unity默认导出的是Android-Eclipse工程,毕竟Eclipse for Android开发在近一两年才开始没落,用户量还是非常巨大的. 个人认为AndroidStudio非常好用,能轻易解决很多Eclipse解决不了或者很难解决的问题. 所以我将Unity导出的Andoid工程分为Eclipse和AndroidStudio两部分. 不过我之后的相关内容都会使用AndroidStudio,希望依然

大数据和「数据挖掘」是何关系?---来自知乎

知乎用户,互联网 244 人赞同 在我读数据挖掘方向研究生的时候:如果要描述数据量非常大,我们用Massive Data(海量数据)如果要描述数据非常多样,我们用Heterogeneous Data(异构数据)如果要描述数据既多样,又量大,我们用Massive Heterogeneous Data(海量异构数据)--如果要申请基金忽悠一笔钱,我们用Big Data(大数据) 编辑于 2014-02-2817 条评论感谢 收藏没有帮助举报作者保留权利 刘知远,NLPer 4 人赞同 我觉得 大数据

开放的智力8:实用「成功学」

可实现的「成功学」 现在我想为这里的年轻人介绍一种可实现的「成功学」.希望这个我自创的理论,可以改变很多人的一生. 当我们评价一个事情值不值得去做.应该花多少精力去做的时候,应该抛弃单一的视角,而是分两个不同的维度来看,一是该事件将给我带来的收益大小(认知.情感.物质.身体方面的收益皆可计入),即「收益值」:二是该收益随时间衰减的速度,我称为「收益半衰期」,半衰期长的事件,对我们的影响会持续得较久较长. 这两个维度正交以后就形成了一个四象限图.我们生活.学习和工作中的所有事情都可以放进这个图里面

Linux 小知识翻译 - 「syslog」

这次聊聊「syslog」. 上次聊了「日志」(lgo).这次说起syslog,一看到log(日志)就明白是怎么回事了.syslog是获取系统日志的工具. 很多UINIX系的OS都采用了这个程序,它承担了「获取系统全部的日志」这个维持系统正常运行的重要任务. syslog的本体是「syslogd」这个daemon(一般翻译成守护进程),常驻内存中获取日志. syslog的特点是可以通过配置文件「/etc/syslog.conf」,对「哪种应用程序?哪种重要度的信息?记录在哪个文件中?」等进行细致的

Linux 小知识翻译 - 「日志」(log)

这次聊聊「日志」. 「日志」主要指系统或者软件留下的「记录」.出自表示「航海日志」的「logbook」. 经常听说「出现问题的时候,或者程序没有安装自己预期的来运行的时候,请看看日志!」. 确实,记录了系统和软件详细运行情况的「日志」是信息的宝库,通过日志来解决问题的事例也非常多. 但事实上,「无论如何也不会看日志」的用户也有很多.理由很简单,日志的信息量非常大,全部用眼睛来看的话是非常吃力的. 而且,英语写的日志也会让英文不好的人敬而远之. 虽说「要养成用眼睛来看日志的习惯」,但实行起来却非常

Linux 小知识翻译 - 「补丁」(patch)

这次,聊聊补丁. 当有bug或者安全漏洞的时候,就会发布补丁.打上补丁之后,就能解决相应的bug或者安全漏洞. 那么,「补丁」到底是什么呢? 「补丁」只有少量的代码,一般都是对程序的一部分进行更新或者追加,包括bug修正,安全漏洞修正,功能追加或者变更等等.当然,只有「补丁」是无法运行的. 即,只有将「补丁」附加到原来的程序中,更新原来的程序后,才能运行. 「补丁(patch)」本来是指「打补丁用的小布头」.「patch」正是为了补足现有的程序,堵住程序漏洞的「布头」. 打「补丁」的时候需要用到