BZOJ 2156 「国家集训队」星际探索(最短路)BZOJ计划
Posted 繁凡さん
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2156 「国家集训队」星际探索(最短路)BZOJ计划相关的知识,希望对你有一定的参考价值。
整理的算法模板合集: ACM模板
实际上是一个全新的精炼模板整合计划
题目链接
https://hydro.ac/d/bzoj/p/2156
众所周知,新世纪的科学很发达,于是 Ray 和 Raven 开始了星际探险,他们在宇宙中开辟了一片空间,建造了 n n n 个空间站。这 n n n 个空间站由一些单向的时空隧道连接,这些时空隧道都有一个穿越指数,穿过这些时空隧道,你可以走到未来或者回到过去,当然,这些都是由穿越指数决定的。有一天,Ray 和 Raven 开始了一场比赛。他们要从一个空间站 s s s 出发去另一个空间站 t t t ,先到的人获胜。Raven 一定会选一条能最快到达 tt 的路线。他希望 Ray 输给他,所以事先在 Ray 的飞船上设定了飞行路径,使得 Ray 从 s s s 到 t t t 只能走一条特定的路径。
但是,Ray 有对策,他有一台能够操纵时空隧道的机器,这台机器每次可以把某一条时空隧道的穿越指数增加或减少 1 1 1,但是因为操纵机器很累,所以 Ray 希望尽可能少改动,当然,如果改动后从某个空间站经过一系列的穿越可以在从这个空间站出发之前回到这个空间站,那么这样的改动是不允许的。修改之后,Raven 依然会走能最快到达终点的路线,所以 Ray 是不可能赢的。但他请你帮助他确定改动时空隧道的方案,使得他能和 Raven 同时到达 t t t。
Solution
大概是国家集训队作业里的水题()
题目大意就是将事先设定好的路线的长度与最短路的差是多少。
我们可以先求一下最短路,然后计算设定的路线的距离,差值就是答案…
Code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef pair <int, int> PII;
const int maxn = 1e5 + 6, maxm = maxn << 1 | 7;
int n, m, s, t, k;
ll ans;
int head[maxn], ver[maxm], edge[maxm], nex[maxm], tot;
bool vis[maxn];
queue <int> q;
map <PII, int> mp;
ll dist[maxn];
int path[maxn];
void add(int x, int y, int z)
{
ver[tot] = y;
edge[tot] = z;
nex[tot] = head[x];
head[x] = tot ++ ;
}
void spfa()
{
memset(dist, 0x3f, sizeof dist);
q.push(s);
vis[1] = 1;
dist[s] = 0;
while(q.size()) {
int x = q.front();
q.pop();
vis[x] = 0;
for (int i = head[x]; ~i; i = nex[i]) {
int y = ver[i];
ll z = edge[i];
if(dist[y] > dist[x] + z) {
dist[y] = dist[x] + z;
if(vis[y] == 0) {
vis[y] = 1;
q.push(y);
}
}
}
}
}
int main()
{
memset(head, -1, sizeof head);
cin >> n >> m;
for (int i = 1; i <= m; ++ i) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
add(x, y, z);
mp[{x, y}] = z;
}
cin >> k;
for (int i = 1; i <= k; ++ i)
scanf("%d", &path[i]);
s = path[1], t = path[k];
ll sum = 0;
for (int i = 1; i < k; ++ i)
sum += mp[{path[i], path[i + 1]}];
spfa();
cout << (sum - dist[t]) << endl;
return 0;
}
以上是关于BZOJ 2156 「国家集训队」星际探索(最短路)BZOJ计划的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ_2622_[2012国家集训队测试]深入虎穴_最短路