题解:AT_cf16_exhibition_final_e Water Distribution
首先
然后让传递水的两个城市
所以最终构成森林,对于一棵树
看到
复杂度
代码
#include<bits/stdc++.h>
using namespace std;
#define db double
const int N = 16;
const db inf = 1e18;
int n, fa[N], m;
db x[N], y[N], v[N], f[1 << N], g[1 << N];
struct edge{int u, v; db w;} e[N * N + 5];
inline int find(int u) {return fa[u] == u ? u : fa[u] = find(fa[u]);}
inline db dist(int a, int b) {return sqrt((x[a] - x[b]) * (x[a] - x[b]) + (y[a] - y[b]) * (y[a] - y[b]));}
signed main(){
cin >> n;
for(int i = 0; i < n; ++i) scanf("%lf%lf%lf", &x[i], &y[i], &v[i]);
for(int S = 1; S < 1 << n; ++S){
m = 0;
for(int i = 0; i < n; ++i)
if((S >> i) & 1){
fa[i] = i, f[S] += v[i];
for(int j = i + 1; j < n; ++j)
if((S >> j) & 1)
e[++m] = {i, j, dist(i, j)};
}
sort(e + 1, e + 1 + m, [](edge A, edge B){return A.w < B.w;});
for(int i = 1; i <= m; ++i){
int fu = find(e[i].u), fv = find(e[i].v);
if(fu != fv) fa[fu] = fv, f[S] -= e[i].w;
}
f[S] /= __builtin_popcount(S);
}
g[0] = inf;
for(int S = 1; S < 1 << n; ++S)
for(int S2 = S; S2; S2 = (S2 - 1) & S)
g[S] = max(g[S], min(g[S ^ S2], f[S2]));
printf("%.9lf", g[(1 << n) - 1]);
return 0;
}