社区讨论
求 hack
P10819[EC Final 2020] City Brain参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mi7560yu
- 此快照首次捕获于
- 2025/11/20 16:00 3 个月前
- 此快照最后确认于
- 2025/11/20 23:59 3 个月前
基本思路:求解出 表示路径交集大小为 的时候,路径的并的最小值加 是多少。这个非常容易维护。
然后三分找答案即可。
结果就是挂了,在模拟赛里面和我挂的还有很多个。
CPP#include <bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
int n, m, k, dst[5005][5005], q[5005], front, rear, s1, s2, t1, t2, dp[5005][5005], res[5005];
vector<int> edges[5005];
void bfs(int s, int *dst) {
front = 1, rear = 0;
for (int i = 1; i <= n; ++i) {
dst[i] = 1ll << 60;
}
q[++rear] = s;
dst[s] = 0;
while (rear + 1 != front) {
int fx = q[front++];
for (auto j : edges[fx]) {
if (dst[j] == 1ll << 60) {
dst[j] = dst[fx] + 1;
q[++rear] = j;
}
}
}
}
double get_ans(int t, int s, int ta, int ts) {
// t -> 相同路径
// s -> 不相同路径
assert(ta >= 0);
assert(ts >= 0);
assert(ta + ts == k);
return (t ? ((double)1.0 / (ta / t + 2) * (ta % t) +
(double)1.0 / (ta / t + 1) * (t - ta % t)) * 2 : 0) +
(s ? (double)1.0 / (ts / s + 2) * (ts % s) +
(double)1.0 / (ts / s + 1) * (s - ts % s) : 0);
}
const int L = 10;
double get_s(int t, int s) {
int l = 0, r = k;
double ans = 1e308;
while (r - l > L) {
int mid1 = l + (r - l) / 3, mid2 = l + (r - l) / 3 * 2;
double ans1 = get_ans(t, s, mid1, k - mid1);
double ans2 = get_ans(t, s, mid2, k - mid2);
ans = min({ans, ans1, ans2});
if (ans1 > ans2) l = mid1;
else r = mid2;
}
for (int i = max(l - L, 0ll); i <= min(r + L, k); ++i) {
ans = min(ans, get_ans(t, s, i, k - i));
}
return ans;
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m >> k;
for (int i = 1; i <= m; ++i) {
int u, v;;
cin >> u >> v;
edges[u].push_back(v);
edges[v].push_back(u);
}
cin >> s1 >> t1 >> s2 >> t2;
for (int i = 1; i <= n; ++i) {
bfs(i, dst[i]);
}
memset(res, 1, sizeof(res));
res[0] = dst[s1][t1] + dst[s2][t2];
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (dst[i][j] <= 5000 && dst[s1][i] <= 5000 && dst[j][t1] <= 5000 && dst[s2][i] <= 5000 && dst[j][t2] <= 5000) {
res[dst[i][j]] = min(res[dst[i][j]], dst[s1][i] + dst[j][t1] + dst[s2][i] + dst[j][t2]);
}
}
}
double ans = 1e308;
for (int i = 0; i <= 5000; ++i) {
if (res[i] <= 12000) {
ans = min(ans, get_s(i, res[i]));
}
}
printf("%.15Lf\n", ans);
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...