[CF543B] Destroying Roads - 最短路
Description
给定无向无权图,求在保证 (s_1,t_1) 间距离不超过 (t_1),(s_2,t_2) 间距离不超过 (t_2) 的情况下,最多能破坏的公路数量。
Solution
如果只有一个约束,显然最短路
考虑有两个约束,那么最短路可能有交,也可能无交
无交的情况,答案就是 m-两条最短路长度和
有交的情况,枚举最短路端点 i,j,然后考虑两种可能的情况
#include <bits/stdc++.h>
using namespace std;
#define int long long
void bfs(const vector<vector<int>> &g, vector<int> &dist, int v0)
{
queue<int> que;
que.push(v0);
fill(dist.begin(), dist.end(), INT_MAX / 2);
dist[v0] = 0;
vector<int> vis(dist.size());
vis[v0] = 1;
while (que.size())
{
int p = que.front();
que.pop();
for (int q : g[p])
{
if (dist[q] > dist[p] + 1)
{
dist[q] = dist[p] + 1;
if (vis[q] == 0)
vis[q] = 1, que.push(q);
}
}
}
}
void calculate_distance(int n, const vector<vector<int>> &g, vector<vector<int>> &d, int v0)
{
vector<int> dist(n + 2);
bfs(g, dist, v0);
for (int i = 1; i <= n; i++)
d[v0][i] = d[i][v0] = dist[i];
}
signed main()
{
int n, m;
cin >> n >> m;
vector<vector<int>> g(n + 2);
vector<vector<int>> d(n + 2, vector<int>(n + 2));
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
int s1, t1, s2, t2, l1, l2;
cin >> s1 >> t1 >> l1 >> s2 >> t2 >> l2;
for (int i = 1; i <= n; i++)
calculate_distance(n, g, d, i);
int len1 = d[s1][t1];
int len2 = d[s2][t2];
if (len1 <= l1 && len2 <= l2)
{
int ans = len1 + len2;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (d[s1][i] + d[i][j] + d[t1][j] <= l1 &&
d[s2][i] + d[i][j] + d[t2][j] <= l2)
ans = min(ans, d[s1][i] + d[s2][i] + d[i][j] + d[t1][j] + d[t2][j]);
if (d[t1][i] + d[i][j] + d[s1][j] <= l1 &&
d[s2][i] + d[i][j] + d[t2][j] <= l2)
ans = min(ans, d[t1][i] + d[s2][i] + d[i][j] + d[s1][j] + d[t2][j]);
}
}
cout << m - ans << endl;
}
else
{
cout << -1;
}
}