加当前弧优化就A了!

P3355 骑士共存问题

ghj1222 @ 2018-12-10 19:58:34

#include <bits/stdc++.h>
using namespace std;

struct edge
{
    int v, ne, flow;
} a[6400010];

int dx[] = {-2, -2, -1, -1, 1, 1, 2, 2}, dy[] = {-1, 1, -2, 2, -2, 2, -1, 1};
int n, m;
bool fucked[210][210];
int id[210][210], totid;
int h[40010], now[40010], tmp = 1;
int src = 40001, dest = 40002;
int d[40010];

void add(int u, int v, int w)
{
    a[++tmp] = (edge){v, h[u], w};
    h[u] = tmp;
}

bool bfs()
{
    queue<int> q;
    q.push(src);
    memset(d, 0xff, sizeof(d));
    d[src] = 0;
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = h[x]; i != 0; i = a[i].ne)
        {
            if (a[i].flow > 0 && d[a[i].v] == -1)
                d[a[i].v] = d[x] + 1, q.push(a[i].v);
        }
    }
    return d[dest] > 0;
}

int dfs(int x, int want)
{
    if (x == dest || want == 0)
        return want;
    int get = 0;
    for (int i = now[x]; i != 0; i = a[i].ne)
    {
        if (d[a[i].v] == d[x] + 1 && a[i].flow > 0)
        {
            int f = dfs(a[i].v, min(want, a[i].flow));
            a[i].flow -= f;
            a[i ^ 1].flow += f;
            want -= f;
            get += f;
        }
        now[x] = i;
        if (want == 0)
            break;
    }
    if (want == 0)
        d[x] = -1;
    return get;
}

inline void read(int &x)
{
    static char ch;
    x = 0;
    ch = getchar();
    while (!isdigit(ch))
        ch = getchar();
    while (isdigit(ch))
        x = x * 10 + ch - 48, ch = getchar();
}

int main()
{
    read(n), read(m);
    for (int x, y, i = 1; i <= m; i++)
        read(x), read(y), fucked[x][y] = true;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (!fucked[i][j])
                id[i][j] = ++totid;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (!fucked[i][j])
            {
                if (!((i ^ j) & 1))
                {
                    add(id[i][j], dest, 1), add(dest, id[i][j], 0);
                }
                else
                {
                    add(src, id[i][j], 1), add(id[i][j], src, 0);
                    for (int d = 0; d < 8; d++)
                    {
                        int nx = i + dx[d], ny = j + dy[d];
                        if (nx < 1 || nx > n || ny < 1 || ny > n || fucked[nx][ny] == true)
                            continue;
                        add(id[i][j], id[nx][ny], 1), add(id[nx][ny], id[i][j], 0);
                    }
                }
            }
    int ans = 0;
    while (bfs())
    {
        for (int i = 1; i <= 40002; i++)
            now[i] = h[i];
        ans += dfs(src, 1e9);
    }
    printf("%d\n", n * n - m - ans);
    return 0;
}

不加当前弧优化第三个点就是过不去,加了直接100ms,没错,就是这么操蛋


by LonelinessMan @ 2018-12-10 19:59:23

so?


by memset0 @ 2018-12-10 20:01:34

@ghj1222 AC 代码请发题解区


by ghj1222 @ 2018-12-10 20:15:51

@memset0 并不想发题解,只是提一句


by memset0 @ 2018-12-10 20:19:03

@ghj1222 。。。


by Celebrate @ 2018-12-22 11:58:38

预流推进也可以ac把


|