题解:P10819 [EC Final 2020] City Brain
哇,写了
思路:
对于两条路径,一定是中间有重合的一段,而不是有两段,否则,对于两个人中间分开的那一段路径一定可以选择一条更短的路走,从而将两段重合路径合并成了一段。
可以枚举重合的路径的两个端点,那么重合的路径长度以及不重合的路径的长度就可以确定了,假设重复端点为
接着处理一些细节即可。
double solve(int b, int a) {
if (a > inff || b > inff) return inff;
if (a == 0 && b == 0) return 0;
int k = tempk;
int v = (k + a + b) / (genhao2 * a + b) ;
int u = genhao2 * v;
if (u > 1) u--;
if (v > 1) v--;
if (u < 1) u = 1;
if (v < 1) v = 1;
// cout << u << " " << v << endl;
k -= a * (u - 1) + b * (v - 1);
ans = a * (2.0 / u) + b * (1.0 / v);
// cout << ans << endl;
while (k != 0) {
if (1 * u * (u + 1) < 2 * v * (v + 1)) {
int time = min(k, a);
ans -= time * (2.0 / (u * (u + 1)));
k -= time;
u++;
} else {
int time = min(k, b);
ans -= time * (1.0 / (v * (v + 1)));
k -= time;
v++;
}
}
return ans;
}
void add(int u, int v) {
to[++sum] = v ;
next_side[sum] = first_side[u] ;
first_side[u] = sum;
}
void bfs(int step, int dis[]) {
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) dis[i] = inff;
queue <int> Q;
vis[step] = 1;
Q.push(step);
dis[step] = 0;
while (!Q.empty()) {
int front_ = Q.front();
Q.pop();
for (int i = first_side[front_]; i != 0; i = next_side[i]) {
int to_ = to[i];
if (vis[to_]) continue;
Q.push(to_);
vis[to_] = 1;
dis[to_] = dis[front_] + 1;
}
}
}