题意
有两边各n个点,相邻的已经有边,现在最多能加k个边,用来连接上下的点,加的边的权值都是0,问从任意一点到另一点的距离的最大值的最小值。
思路
注意到n很小,所以我们可以状态压缩一下,用来说明哪个点要连边,然后Floyd搞搞。
做完这题后我觉得我不能满足于仅仅做简单版的,于是我跑去Div1看了一下。
然后我就回来了。
代码
class BridgeBuildingDiv2 {
public:
int G[100][100], n;
int Check()
{
int dis = -1;
for (int k = 0; k < 2*n; k++)
{
G[k][k] = 0;
for (int i = 0; i < 2*n; i++) if (G[i][k] != INF)
for (int j = 0; j < 2*n; j++) if (G[k][j] != INF)
G[i][j] = G[j][i] = min(G[i][j], G[i][k] + G[k][j]);
}
for (int i = 0; i < 2*n; i++)
for (int j = 0; j < 2*n; j++) dis = max(dis, G[i][j]);
return dis;
}
int minDiameter(vector<int> a, vector<int> b, int K) {
n = SZ(a)+1;
int ans = INF;
for (int i = 0; i < (1<<n); i++)
{
MS(G, INF);
for (int i = 0; i < SZ(a); i++) G[i][i+1] = a[i];
for (int i = 0; i < SZ(b); i++) G[i+n][i+1+n] = b[i];
if (__builtin_popcount(i) > K) continue;
for (int j = 0; j < n; j++)
if ((i>>j)&1) G[j][j+n] = G[j+n][j] = 0;
ans = min(ans, Check());
}
return ans;
}
};