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;
}
posted @ 2021-11-11 17:45  Kinuhata  阅读(18)  评论(0)    收藏  举报