专栏文章
题解:P14318 「ALFR Round 11」B 行走 (walk)
P14318题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minhmk8i
- 此快照首次捕获于
- 2025/12/02 02:33 3 个月前
- 此快照最后确认于
- 2025/12/02 02:33 3 个月前
首先判掉小 A 或小 B 走无法到达目标地点的情况。
显然,小 A 和小 B 走到目标地点的边数一定可以最小化,否则一定可以造出相对应的边数最小的不更劣的方案。
然后这个题就变成了一道数学题。
记小 A 和小 B 走到目标地点的边数为总和的最小值为 。
那么这道题相当于给定 ,求 。
考虑到如果有还可以更接近的两项及即 ,则 (读者自证)。
所以可以得到一定是 中的数一定是 (可以没有 )。
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int T, n, m, s, t, x, y, dist[N];
ll k;
vector<int> g[N];
queue<int> q;
int get(int s, int t) {
memset(dist, -1, sizeof dist);
dist[s] = 0;
q.push(s);
while(!q.empty()) {
int u = q.front(); q.pop();
for(int v : g[u])
if(!~dist[v]) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
return dist[t];
}
int main()
{
scanf("%d", &T);
while(T --) {
scanf("%d%d%lld", &n, &m, &k);
for(int i = 1; i <= n; i ++) g[i].clear();
while(m --) {
scanf("%d%d", &x, &y);
g[x].push_back(y), g[y].push_back(x);
}
scanf("%d%d%d%d", &s, &t, &x, &y);
int a = get(s, t), b = get(x, y);
if(!~a || !~b) {
puts("-1");
continue;
}
int v = a + b;
if(!v) { // 注意特判这里
puts("0");
continue;
}
int lef = k % v;
printf("%.12lf\n", lef * 1.0 / (k / v + 2) + (v - lef) * 1.0 / (k / v + 1));
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...