CF543B Destroying Roads 题解
边权全为1的无向连通图,最大化不在s1到t1,s2到t2两条路径上的边数.\(n \le 3000\)
直接最短路明显是错的,因为将两路径重合部分计算了两次.由于n只有3000,可以先求出全源最短路(别nt用floyd),然后枚举重合部分的左右端点,注意s1,s2可能同侧或依次,分类讨论两种情况即可.
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int N = 3005, M = 3005 * 3005, INF = 0x3f3f3f3f;
int read()
{
int f = 1, x = 0;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = x * 10 + (ch ^ 48);
ch = getchar();
}
return x * f;
}
int n, m, s1, t1, l1, s2, t2, l2, ans = -1;
int dis[N][N];
int cnt, head[N];
struct edge
{
int to, next;
} e[M];
void add(int u, int v)
{
e[++cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}
void bfs(int s)
{
queue<int> q;
while (!q.empty())
q.pop();
dis[s][s] = 0;
q.push(s);
while (!q.empty())
{
int x = q.front();
q.pop();
for (int i = head[x]; i; i = e[i].next)
{
int v = e[i].to;
if (dis[s][v] != INF)
continue;
dis[s][v] = dis[s][x] + 1;
q.push(v);
}
}
}
int main()
{
n = read(), m = read();
for (int i = 1; i <= m; i++)
{
int u = read(), v = read();
add(u, v), add(v, u);
}
cin >> s1 >> t1 >> l1 >> s2 >> t2 >> l2;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
dis[i][j] = INF;
for (int i = 1; i <= n; i++)
bfs(i);
if (dis[s1][t1] <= l1 && dis[s2][t2] <= l2)
ans = max(ans, m - dis[s1][t1] - dis[s2][t2]);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (dis[s1][i] + dis[i][j] + dis[j][t1] <= l1 && dis[s2][i] + dis[i][j] + dis[j][t2] <= l2)
ans = max(ans, m - dis[s1][i] - dis[j][t1] - dis[s2][i] - dis[j][t2] - dis[i][j]);
if (dis[s1][i] + dis[i][j] + dis[j][t1] <= l1 && dis[t2][i] + dis[i][j] + dis[j][s2] <= l2)
ans = max(ans, m - dis[s1][i] - dis[j][t1] - dis[t2][i] - dis[j][s2] - dis[i][j]);
}
cout << ans << endl;
}
本文来自博客园,作者:Kinuhata,转载请注明原文链接:https://www.cnblogs.com/KinuhataSaiai/p/15540954.html